#include "plants.h"
#include <bits/stdc++.h>
#define all(x) (x).begin(),(x).end()
using namespace std;
using ll = long long;
#define sz(x) ((int)(x).size())
int K, N;
const int nmax = 2e5 + 5;
template<typename T>
struct AINT {
vector<T> aint;
int n;
void init(int n_) {
n = n_;
aint.assign(2 * n + 5, T());
}
template<int dir = 0, class CB> void walk(CB&& cb) { walk(cb, 0, n - 1); }
template<int dir = 0, class CB> void walk(CB&& cb, int l, int r) { walk(cb, l, r, 1, 0, n - 1); }
template<int dir = 0, class CB> void walk(CB&& cb, int l, int r, int node, int cl, int cr) {
if(cr < l || r < cl) return;
if(l <= cl && cr <= r && !cb(aint[node], cl, cr)) return;
int mid = (cl + cr) >> 1, L = node + 1, R = node + (mid - cl + 1) * 2;
aint[node].push(aint[L], aint[R]);
if(dir == 0) { walk(cb, l, r, L, cl, mid); walk(cb, l, r, R, mid + 1, cr); }
if(dir == 1) { walk(cb, l, r, R, mid + 1, cr); walk(cb, l, r, L, cl, mid); }
aint[node].pull(aint[L], aint[R]);
}
};
struct MinFindUnit {
int mn;
int lazy = 0;
void push(MinFindUnit& L, MinFindUnit& R) {
if(lazy == 0) return;
L.lazy += lazy;
R.lazy += lazy;
R.mn += lazy;
L.mn += lazy;
lazy = 0;
return;
}
void pull(MinFindUnit& L, MinFindUnit& R) {
mn = min(L.mn, R.mn);
return;
}
};
struct MinFind : AINT<MinFindUnit> {
int query_next(int t, int limit) {
if(aint[1].mn > limit) return -1;
for(int itt = 0; itt < 2; itt++) {
walk([&](auto& a, int cl, int cr) {
if(t < cl) return 0;
if(cr < t) return 0;
if(a.mn > limit) {
t = cr + 1;
return 0;
}
if(cl == cr) { return 0; }
return 1;
}, t, n - 1);
if(t == n) t = 0;
}
return t;
}
int query_prev(int t, int limit) {
if(aint[1].mn > limit) return -1;
for(int itt = 0; itt < 2; itt++) {
walk<1>([&](auto& a, int cl, int cr) {
if(t < cl) return 0;
if(cr < t) return 0;
if(a.mn > limit) {
t = cl - 1;
return 0;
}
if(cl == cr) { return 0; }
return 1;
}, 0, t);
if(t == -1) t = n - 1;
}
return t;
}
void add(int l, int r, int x) {
walk([&](auto& a, int cl, int cr) {
a.mn += x;
a.lazy += x;
return 0;
}, l, r);
}
void set(int p, int x) {
walk([&](auto& a, int cl, int cr) {
if(cl != cr) return 1;
a.mn = x;
a.lazy = 0;
return 0;
}, p, p);
}
void set(int l, int r, int x) {
walk([&](auto& a, int cl, int cr) {
if(cl != cr) return 1;
a.mn = x;
a.lazy = 0;
return 0;
}, l, r);
}
};
namespace Queue {
int next[nmax];
MinFind inside;
auto rdist = [](int x, int d) {
return d < x? N - x + d : d - x;
};
auto ldist = [](int x, int d) {
return d <= x? x - d : x + N - d;
};
set<int> heads;
void init() {
inside.init(N);
inside.set(0, N - 1, 1);
//for(int i = 0; i < N; i++)
//inside.walk([&](auto& a, int cl, int cr) { cerr << a.mn << ' '; return 0; }, i, i); cerr << '\n';
}
void insert(int node) {
//for(int i = 0; i < N; i++)
//inside.walk([&](auto& a, int cl, int cr) { cerr << a.mn << ' '; return 0; }, i, i); cerr << '\n';
heads.emplace(node);
inside.set(node, 0);
next[node] = -1;
//for(int i = 0; i < N; i++)
//inside.walk([&](auto& a, int cl, int cr) { cerr << a.mn << ' '; return 0; }, i, i); cerr << '\n';
//cerr << "insert " << node << '\n';
int nx = inside.query_next((node + 1) % N, 0);
int pr = inside.query_prev((node - 1 + N) % N, 0);
//cerr << nx << ' ' << pr << '\n';
//inside.walk([&](auto& a, int cl, int cr) { cerr << a.mn << '\n'; return 0; }, nx, nx);
//inside.walk([&](auto& a, int cl, int cr) { cerr << a.mn << '\n'; return 0; }, pr, pr);
//cerr << '\n';
if(nx != node && rdist(node, nx) < K) {
next[node] = nx;
if(heads.count(nx)) heads.erase(nx);
}
if(pr != node && ldist(node, pr) < K) {
heads.erase(node);
next[pr] = node;
}
}
vector<int> prune() {
vector<int> rez;
for(auto x : heads)
rez.emplace_back(x), inside.set(x, 1);
heads.clear();
for(auto x : rez)
if(next[x] != -1) heads.emplace(next[x]);
return rez;
}
}
vector<int> topsort;
#define left ofia
#define right goa
int left[nmax][18], jumpl[nmax][18];
int right[nmax][18], jumpr[nmax][18];
void init(int k__, std::vector<int> r) {
auto T = r;
K = k__;
N = sz(r);
topsort.resize(N);
Queue::init();
vector<int> erased(N, 0);
for(int i = 0; i < sz(r); i++)
if(r[i] == 0) erased[i] = 1, Queue::insert(i);
int color = 0;
while(sz(Queue::heads)) {
auto rem = Queue::prune();
++color;
for(auto x : rem) topsort[x] = color;
for(auto x : rem) {
for(int i = (x - 1 + N) % N, d = 1; d < K; d++, i = (i - 1 + N) % N) {
if(erased[i]) continue;
r[i]--;
if(r[i] == 0) erased[i] = 1, Queue::insert(i);
}
}
}
for(int x = 0; x < sz(r); x++) {
int mn = -1;
jumpl[x][0] = 0;
for(int i = (x - 1 + N) % N, d = 1; d < K; d++, i = (i - 1 + N) % N) {
if(topsort[i] > topsort[x])
mn = (mn == -1? i : topsort[mn] < topsort[i]? mn : i);
}
left[x][0] = mn == -1? x : mn;
jumpl[x][0] = left[x][0] <= x? x - left[x][0] : x + N - left[x][0];
mn = -1;
jumpr[x][0] = 0;
for(int i = (x + 1 + N) % N, d = 1; d < K; d++, i = (i + 1 + N) % N) {
if(topsort[i] > topsort[x])
mn = (mn == -1? i : topsort[mn] < topsort[i]? mn : i);
}
right[x][0] = mn == -1? x : mn;
jumpr[x][0] = (right[x][0] >= x? right[x][0] - x : N - x + right[x][0]);
}
for(int step = 1; step < 18; step++)
for(int i = 0; i < N; i++)
left[i][step] = left[left[i][step - 1]][step - 1], jumpl[i][step] = jumpl[i][step - 1] + jumpl[left[i][step - 1]][step - 1],
right[i][step] = right[right[i][step - 1]][step - 1], jumpr[i][step] = jumpr[i][step - 1] + jumpr[right[i][step - 1]][step - 1];
return;
}
bool compare_smaller(int x, int y) {
auto rdist = [&](int d) {
return d < x? N - x + d : d - x;
};
auto ldist = [&](int d) {
return d <= x? x - d : x + N - d;
};
int st = x, buffer = rdist(y);
for(int i = 17; i >= 0; i--) {
if(buffer < jumpr[st][i]) continue;
buffer -= jumpr[st][i];
st = right[st][i];
}
if(st == y) return 1;
if(rdist(y) - rdist(st) < K && topsort[y] > topsort[st]) return 1;
st = x;
buffer = ldist(y);
for(int i = 17; i >= 0; i--) {
if(buffer < jumpl[st][i]) continue;
buffer -= jumpl[st][i];
st = left[st][i];
}
if(st == y) return 1;
if(ldist(y) - ldist(st) < K && topsort[y] > topsort[st]) return 1;
return 0;
}
int compare_plants(int x, int y) {
return compare_smaller(x, y)? 1 : compare_smaller(y, x)? -1 : 0;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
6492 KB |
Output is correct |
2 |
Correct |
1 ms |
6492 KB |
Output is correct |
3 |
Correct |
1 ms |
6492 KB |
Output is correct |
4 |
Correct |
1 ms |
6492 KB |
Output is correct |
5 |
Correct |
1 ms |
6492 KB |
Output is correct |
6 |
Correct |
58 ms |
10164 KB |
Output is correct |
7 |
Correct |
99 ms |
17748 KB |
Output is correct |
8 |
Correct |
435 ms |
70792 KB |
Output is correct |
9 |
Correct |
449 ms |
69972 KB |
Output is correct |
10 |
Correct |
427 ms |
69716 KB |
Output is correct |
11 |
Correct |
411 ms |
69712 KB |
Output is correct |
12 |
Correct |
413 ms |
69712 KB |
Output is correct |
13 |
Correct |
350 ms |
69716 KB |
Output is correct |
14 |
Correct |
447 ms |
69716 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
6492 KB |
Output is correct |
2 |
Correct |
1 ms |
6492 KB |
Output is correct |
3 |
Correct |
1 ms |
6492 KB |
Output is correct |
4 |
Correct |
1 ms |
6492 KB |
Output is correct |
5 |
Incorrect |
1 ms |
6492 KB |
Output isn't correct |
6 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
6492 KB |
Output is correct |
2 |
Correct |
1 ms |
6492 KB |
Output is correct |
3 |
Correct |
1 ms |
6492 KB |
Output is correct |
4 |
Correct |
1 ms |
6492 KB |
Output is correct |
5 |
Incorrect |
1 ms |
6492 KB |
Output isn't correct |
6 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
6492 KB |
Output is correct |
2 |
Incorrect |
1 ms |
6492 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
6492 KB |
Output is correct |
2 |
Correct |
1 ms |
6492 KB |
Output is correct |
3 |
Correct |
1 ms |
6492 KB |
Output is correct |
4 |
Correct |
1 ms |
6492 KB |
Output is correct |
5 |
Correct |
1 ms |
6488 KB |
Output is correct |
6 |
Incorrect |
2 ms |
6488 KB |
Output isn't correct |
7 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
6492 KB |
Output is correct |
2 |
Correct |
1 ms |
6492 KB |
Output is correct |
3 |
Correct |
1 ms |
6492 KB |
Output is correct |
4 |
Correct |
1 ms |
6492 KB |
Output is correct |
5 |
Incorrect |
2 ms |
6492 KB |
Output isn't correct |
6 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
6492 KB |
Output is correct |
2 |
Correct |
1 ms |
6492 KB |
Output is correct |
3 |
Correct |
1 ms |
6492 KB |
Output is correct |
4 |
Correct |
1 ms |
6492 KB |
Output is correct |
5 |
Correct |
1 ms |
6492 KB |
Output is correct |
6 |
Correct |
58 ms |
10164 KB |
Output is correct |
7 |
Correct |
99 ms |
17748 KB |
Output is correct |
8 |
Correct |
435 ms |
70792 KB |
Output is correct |
9 |
Correct |
449 ms |
69972 KB |
Output is correct |
10 |
Correct |
427 ms |
69716 KB |
Output is correct |
11 |
Correct |
411 ms |
69712 KB |
Output is correct |
12 |
Correct |
413 ms |
69712 KB |
Output is correct |
13 |
Correct |
350 ms |
69716 KB |
Output is correct |
14 |
Correct |
447 ms |
69716 KB |
Output is correct |
15 |
Correct |
1 ms |
6492 KB |
Output is correct |
16 |
Correct |
1 ms |
6492 KB |
Output is correct |
17 |
Correct |
1 ms |
6492 KB |
Output is correct |
18 |
Correct |
1 ms |
6492 KB |
Output is correct |
19 |
Incorrect |
1 ms |
6492 KB |
Output isn't correct |
20 |
Halted |
0 ms |
0 KB |
- |