Разбор
Tutorial is loading...
Решение (Ajosteen)
#include <bits/stdc++.h>
using namespace std;
int main() {
int s, a, b, c;
int t;
cin >> t;
for(int i = 0; i < t; ++i){
cin >> s >> a >> b >> c;
s /= c;
int x = s / a;
s %= a;
long long res = x * 1LL * (a + b);
res += s;
cout << res << endl;
}
return 0;
}
1065B - Вася и изолированные вершины
Разбор
Tutorial is loading...
Решение (Ajosteen)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
long long m;
cin >> n >> m;
long long cur = 1;
long long rem = m;
while(rem > 0){
long long d = min(cur, rem);
rem -= d;
++cur;
}
assert(rem == 0);
long long res = n;
if(cur > 1) res = n - cur;
cout << max(0ll, n - m * 2) << ' ' << res << endl;
return 0;
}
Разбор
Tutorial is loading...
Решение (Ajosteen)
#include <bits/stdc++.h>
using namespace std;
const int N = int(2e5) + 9;
int n, k, h;
int need = int(1e9);
int cnt[N];
int main() {
scanf("%d %d", &n, &k);
for(int i = 0; i < n; ++i){
int x;
scanf("%d", &x);
h = max(h, x);
need = min(need, x);
++cnt[x];
}
int pos = N - 1;
int res = 0;
long long sum = 0;
int c = 0;
while(true){
long long x = sum - c * 1LL * (pos - 1);
if(x > k){
++res;
h = pos;
sum = pos * 1LL * c;
}
--pos;
if(pos == need) break;
c += cnt[pos];
sum += cnt[pos] * 1LL * pos;
}
if(h != need) ++res;
cout << res << endl;
}
Разбор
Tutorial is loading...
Решение (PikMike)
#include <bits/stdc++.h>
#define forn(i, n) for (int i = 0; i < int(n); i++)
#define mp make_pair
#define x first
#define y second
using namespace std;
typedef pair<int, int> pt;
const int N = 12;
const int M = 305;
const int INF = 1e9;
int n;
int a[N][N];
pt pos[N * N];
pt dist[M][M];
pt operator +(const pt &a, const pt &b){
return mp(a.x + b.x, a.y + b.y);
}
int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[] = { 1, 2, 2, 1, -1, -2, -2, -1};
bool in(int x, int y){
return (0 <= x && x < n && 0 <= y && y < n);
}
int get(int x, int y, int p){
return x * n * 3 + y * 3 + p;
}
pt dp[N * N][3];
int main() {
scanf("%d", &n);
forn(i, n) forn(j, n){
scanf("%d", &a[i][j]);
--a[i][j];
pos[a[i][j]] = mp(i, j);
}
forn(i, M) forn(j, M) dist[i][j] = mp(INF, INF);
forn(i, M) dist[i][i] = mp(0, 0);
forn(x, n) forn(y, n){
forn(i, 8){
int nx = x + dx[i];
int ny = y + dy[i];
if (in(nx, ny))
dist[get(x, y, 0)][get(nx, ny, 0)] = mp(1, 0);
}
for (int i = -n + 1; i <= n - 1; ++i){
int nx = x + i;
int ny = y + i;
if (in(nx, ny))
dist[get(x, y, 1)][get(nx, ny, 1)] = mp(1, 0);
ny = y - i;
if (in(nx, ny))
dist[get(x, y, 1)][get(nx, ny, 1)] = mp(1, 0);
}
forn(i, n){
int nx = x;
int ny = i;
dist[get(x, y, 2)][get(nx, ny, 2)] = mp(1, 0);
nx = i;
ny = y;
dist[get(x, y, 2)][get(nx, ny, 2)] = mp(1, 0);
}
forn(i, 3) forn(j, 3){
if (i != j){
dist[get(x, y, i)][get(x, y, j)] = mp(1, 1);
}
}
}
forn(k, M) forn(i, M) forn(j, M)
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
forn(i, N * N) forn(j, 3) dp[i][j] = mp(INF, INF);
dp[0][0] = dp[0][1] = dp[0][2] = mp(0, 0);
forn(i, n * n - 1) forn(j, 3) forn(k, 3)
dp[i + 1][k] = min(dp[i + 1][k], dp[i][j] + dist[get(pos[i].x, pos[i].y, j)][get(pos[i + 1].x, pos[i + 1].y, k)]);
pt ans = mp(INF, INF);
ans = min(ans, dp[n * n - 1][0]);
ans = min(ans, dp[n * n - 1][1]);
ans = min(ans, dp[n * n - 1][2]);
printf("%d %d\n", ans.x, ans.y);
return 0;
}
Разбор
Tutorial is loading...
Решение (PikMike)
#include <bits/stdc++.h>
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
const int N = 200 * 1000 + 13;
const int MOD = 998244353;
int n, m, A;
int b[N];
int add(int a, int b){
a += b;
if (a >= MOD)
a -= MOD;
return a;
}
int mul(int a, int b){
return (a * 1ll * b) % MOD;
}
int binpow(int a, int b){
int res = 1;
while (b){
if (b & 1)
res = mul(res, a);
a = mul(a, a);
b >>= 1;
}
return res;
}
int cnt(int x){
int base = binpow(A, x);
return mul(add(mul(base, base), base), (MOD + 1) / 2);
}
int main() {
scanf("%d%d%d", &n, &m, &A);
forn(i, m)
scanf("%d", &b[i]);
int ans = binpow(A, n - b[m - 1] * 2);
ans = mul(ans, cnt(b[0]));
forn(i, m - 1)
ans = mul(ans, cnt(b[i + 1] - b[i]));
printf("%d\n", ans);
return 0;
}
1065F - Вверх и вниз по дереву
Разбор
Tutorial is loading...
Решение (adedalic)
#include<bits/stdc++.h>
using namespace std;
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)
#define sz(a) int((a).size())
#define x first
#define y second
typedef long long li;
typedef pair<int, int> pt;
template<class A, class B> ostream& operator <<(ostream& out, const pair<A, B> &p) {
return out << "(" << p.x << ", " << p.y << ")";
}
template<class A> ostream& operator <<(ostream& out, const vector<A> &v) {
out << "[";
fore(i, 0, v.size()) {
if(i) out << ", ";
out << v[i];
}
return out << "]";
}
const int INF = int(1e9);
const li INF64 = li(1e18);
const int N = 1000 * 1000 + 555;
int n, k;
vector<int> g[N];
inline bool read() {
if(!(cin >> n >> k))
return false;
fore(i, 1, n) {
int p; assert(scanf("%d", &p) == 1);
p--;
g[p].push_back(i);
g[i].push_back(p);
}
return true;
}
int h[N];
pt drev[N];
void calcRev(int v, int p) {
drev[v] = pt(INF, 0);
for(int to : g[v]) {
if(to == p) continue;
h[to] = h[v] + 1;
calcRev(to, v);
if(drev[to].x <= h[v]) {
drev[v].x = min(drev[v].x, drev[to].x);
drev[v].y += drev[to].y;
}
}
if(p >= 0 && g[v].size() == 1)
drev[v] = pt(h[v] - k, 1);
}
int d[N];
void calcAns(int v, int p) {
d[v] = (p >= 0 && g[v].size() == 1);
for(int to : g[v]) {
if(to == p) continue;
calcAns(to, v);
int tmp = drev[v].y;
if(drev[to].x <= h[v])
tmp -= drev[to].y;
d[v] = max(d[v], tmp + d[to]);
}
}
inline void solve() {
h[0] = 0;
calcRev(0, -1);
calcAns(0, -1);
cout << d[0] << endl;
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
int tt = clock();
#endif
cout << fixed << setprecision(15);
if(read()) {
solve();
#ifdef _DEBUG
cerr << "TIME = " << clock() - tt << endl;
tt = clock();
#endif
}
return 0;
}
Разбор
Tutorial is loading...
Решение (BledDest)
#include <bits/stdc++.h>
using namespace std;
typedef long long li;
const li INF64 = li(1e18);
li add(li x, li y)
{
return min(x + y, INF64);
}
const int N = 243;
int A1[N][2];
li A2[N][N];
int A3[N][N];
int n, m;
li k;
int z;
int p[N];
void build(const string& s)
{
z = (int)(s.size());
p[0] = 0;
for(int i = 1; i < z; i++)
{
int j = p[i - 1];
while(j > 0 && s[j] != s[i])
j = p[j - 1];
if(s[j] == s[i])
j++;
p[i] = j;
}
for(int i = 0; i <= z; i++)
for(int j = 0; j < 2; j++)
{
if(i < z && s[i] == char('0' + j))
A1[i][j] = i + 1;
else if(i == 0)
A1[i][j] = 0;
else
A1[i][j] = A1[p[i - 1]][j];
}
for(int i = 0; i <= z; i++)
for(int j = 0; j < 2; j++)
{
A3[i][j] = A1[i][j];
A2[i][j] = (A3[i][j] == z ? 1 : 0);
}
for(int i = 2; i <= n; i++)
for(int j = 0; j <= z; j++)
{
A3[j][i] = A3[A3[j][i - 2]][i - 1];
A2[j][i] = add(A2[j][i - 2], A2[A3[j][i - 2]][i - 1]);
}
}
int main()
{
cin >> n >> k >> m;
string cur = "";
for(int i = 0; i < m; i++)
{
if(cur != "") build(cur);
li x = 0;
if(cur != "" && A3[0][n] == i)
x = 1;
if(k == 1 && x == 1)
break;
k -= x;
build(cur + '0');
li x1 = A2[0][n];
if(k > x1)
{
cur += '1';
k -= x1;
}
else
cur += '0';
}
cout << cur << endl;
return 0;
}