#include "plants.h"
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 3;
int r_arr[N], p[N], k, n;
struct Segment_Tree{
struct Node{
int mn;
array<int, 2> prev_zero;
Node(){}
Node(int mn, int i): mn(mn), prev_zero({i, 0}){}
friend Node merge(const Node &l, const Node &r){
Node ret;
ret.mn = min(l.mn, r.mn);
if(r.prev_zero[1] >= k) ret.prev_zero = r.prev_zero;
else if(l.prev_zero[1]) ret.prev_zero = l.prev_zero;
else ret.prev_zero = r.prev_zero;
return ret;
}
};
Node nd[4 * N];
int lp[4 * N];
void init(int i = 0, int l = 0, int r = n - 1){
if(l == r){
nd[i] = Node(r_arr[l], l);
return;
}
int mid = (l + r) >> 1;
init(2 * i + 1, l, mid);
init(2 * i + 2, mid + 1, r);
nd[i] = merge(nd[2 * i + 1], nd[2 * i + 2]);
}
void push(int i, int l, int r){
nd[i].mn += lp[i];
if(l != r){
lp[2 * i + 1] += lp[i];
lp[2 * i + 2] += lp[i];
}
lp[i] = 0;
}
int query(int i = 0, int l = 0, int r = n - 1){
push(i, l, r);
return nd[i].prev_zero[0];
}
int get_next_zero(int s, int i = 0, int l = 0, int r = n - 1){
if(l > r) return n;
push(i, l, r);
if(r < s || nd[i].mn) return n;
if(l == r) return l;
int mid = (l + r) >> 1;
int l_val = get_next_zero(s, 2 * i + 1, l, mid);
if(l_val != n) return l_val;
return get_next_zero(s, 2 * i + 2, mid + 1, r);
}
int get_prev_zero(int s, int i = 0, int l = 0, int r = n - 1){
if(l > r) return -1;
push(i, l, r);
if(l > s || nd[i].mn) return -1;
if(l == r) return l;
int mid = (l + r) >> 1;
int r_val = get_prev_zero(s, 2 * i + 2, mid + 1, r);
if(r_val != -1) return r_val;
return get_prev_zero(s, 2 * i + 1, l, mid);
}
void update_prev_zero(int s, int i = 0, int l = 0, int r = n - 1){
if(l > r) return;
push(i, l, r);
if(l > s || r < s) return;
if(l == r){
nd[i].prev_zero = {s, s - get_prev_zero(s - 1, 0, 0, n - 1)};
return;
}
int mid = (l + r) >> 1;
update_prev_zero(s, 2 * i + 1, l, mid);
update_prev_zero(s, 2 * i + 2, mid + 1, r);
nd[i] = merge(nd[2 * i + 1], nd[2 * i + 2]);
}
void update_zeroes(int l2, int r2, int i = 0, int l = 0, int r = n - 1){
if(l > r) return;
push(i, l, r);
if(nd[i].mn) return;
if(r < l2 || r2 < l) return;
if(l == r){
update_prev_zero(l, i, l, r);
return;
}
int mid = (l + r) >> 1;
update_zeroes(l2, r2, 2 * i + 1, l, mid);
update_zeroes(l2, r2, 2 * i + 2, mid + 1, r);
nd[i] = merge(nd[2 * i + 1], nd[2 * i + 2]);
}
void change_value(int s, int val, int i = 0, int l = 0, int r = n - 1){
if(l > r) return;
push(i, l, r);
if(r < s || s < l) return;
if(l == r){
nd[i] = Node(val, s);
return;
}
int mid = (l + r) >> 1;
change_value(s, val, 2 * i + 1, l, mid);
change_value(s, val, 2 * i + 2, mid + 1, r);
nd[i] = merge(nd[2 * i + 1], nd[2 * i + 2]);
}
void update(int l2, int r2, int val, int i = 0, int l = 0, int r = n - 1){
if(l > r) return;
push(i, l, r);
if(r < l2 || r2 < l) return;
if(l2 <= l && r <= r2){
lp[i]+=val;
push(i, l, r);
return;
}
int mid = (l + r) >> 1;
update(l2, r2, val, 2 * i + 1, l, mid);
update(l2, r2, val, 2 * i + 2, mid + 1, r);
nd[i] = merge(nd[2 * i + 1], nd[2 * i + 2]);
}
} st;
struct Fenwick{
int a[N];
Fenwick(){}
void clear(){
fill(a, a + N, 0);
}
void update(int i, int v){
for(++i; i < N; i+=i&-i)
a[i] += v;
}
int query(int i){
int ans = 0;
for(++i; i >= 1; i-=i&-i)
ans += a[i];
return ans;
}
int query(int l, int r){
return query(r) - query(l - 1);
}
} f;
const int LOGN = 18;
int nxt[2][LOGN][N];
void init(int _k, vector<int> _r) {
k = _k;
n = _r.size();
for(int i = 0; i < _r.size(); ++i)
r_arr[i] = _r[i];
st.init();
st.update_zeroes(0, n - 1);
for(int i = n - 1; i >= 0; --i){
int idx = st.query();
p[idx] = i;
//cout << idx << " idx" << endl;
st.change_value(idx, n);
if(idx){
st.update(max(idx - (k - 1), 0), idx - 1, -1);
st.update_zeroes(max(idx - (k - 1), 0), idx - 1);
}
if(idx < k - 1){
st.update(n - ((k - 1) - idx), n - 1, -1);
st.update_zeroes(n - ((k - 1) - idx), n - 1);
}
int nxt = st.get_next_zero(idx + 1);
if(nxt != n) st.update_prev_zero(nxt);
}
set<array<int, 2>> s;
for(int i = n - 1; i > n - k; --i)
s.insert({p[i], i});
for(int i = 0; i < n; ++i){
auto it = s.lower_bound({p[i], 0});
if(it == s.end()) nxt[0][0][i] = -1;
else nxt[0][0][i] = (*it)[1];
int prev_i = (i - (k - 1) + n) % n;
s.erase({p[prev_i], prev_i});
s.insert({p[i], i});
}
s.clear();
for(int i = 0; i < k - 1; ++i)
s.insert({p[i], i});
for(int i = n - 1; i >= 0; --i){
auto it = s.lower_bound({p[i], 0});
if(it == s.end()) nxt[1][0][i] = -1;
else nxt[1][0][i] = (*it)[1];
int prev_i = (i + (k - 1)) % n;
s.erase({p[prev_i], prev_i});
s.insert({p[i], i});
}
for(int i = 1; i < LOGN; ++i)
for(int j = 0; j < n; ++j){
int &ans = nxt[0][i][j];
int node_2 = nxt[0][i - 1][j];
if(node_2 == -1){
ans = -1;
continue;
}
int node_3 = nxt[0][i - 1][node_2];
if(node_3 == -1){
ans = node_3;
continue;
}
if(i < node_2){
if(node_3 > node_2 || node_3 <= j) ans = -1;
else ans = node_3;
}
else{
if(node_3 > node_2 && node_3 <= j) ans = -1;
else ans = node_3;
}
}
for(int i = 1; i < LOGN; ++i)
for(int j = 0; j < n; ++j){
int &ans = nxt[1][i][j];
int node_2 = nxt[1][i - 1][j];
if(node_2 == -1){
ans = -1;
continue;
}
int node_3 = nxt[1][i - 1][node_2];
if(node_3 == -1){
ans = node_3;
continue;
}
if(i < node_2){
if(node_3 >= j && node_3 < node_2) ans = -1;
else ans = node_3;
}
else{
if(node_3 >= j || node_3 < node_2) ans = -1;
else ans = node_3;
}
}
//cout << "done preprocessing" << endl;
}
int get_dist(int x, int y){
return min(abs(x - y), min(abs(x + n - y), abs(y + n - x)));
}
bool connected(int x, int y){
if(get_dist(x, y) <= k - 1) return true;
if(p[x] > p[y]) swap(x, y);
int target = (y + (k - 1)) % n;
int curr_x = x;
for(int i = LOGN - 1; i >= 0; --i){
int cand = nxt[0][i][curr_x];
if(cand != -1){
if(curr_x < target){
if(cand < curr_x || target < cand)
curr_x = cand;
}
else{
if(target < cand && cand < curr_x)
curr_x = cand;
}
}
}
curr_x = nxt[0][0][curr_x];
if(curr_x != -1 && get_dist(y, curr_x) <= k - 1)
if(p[curr_x] <= p[y])
return true;
target = (y - (k - 1) + n) % n;
curr_x = x;
for(int i = LOGN - 1; i >= 0; --i){
int cand = nxt[1][i][curr_x];
if(cand != -1){
if(curr_x < target){
if(curr_x < cand && cand < target)
curr_x = cand;
}
else{
if(curr_x < cand || cand < target)
curr_x = cand;
}
}
}
curr_x = nxt[1][0][curr_x];
if(curr_x != -1 && get_dist(y, curr_x) <= k - 1)
if(p[curr_x] <= p[y])
return true;
return false;
}
int compare_plants(int x, int y) {
if(!connected(x, y)) return 0;
return (p[x] > p[y]) ? 1 : -1;
}
/*
4 3 2
0 1 1 2
0 2
1 2
*/
/*
4 2 2
0 1 0 1
0 3
1 3
*/
/*
4 3 2
1 1 0 2
0 1
0 2
*/
Compilation message
plants.cpp: In function 'void init(int, std::vector<int>)':
plants.cpp:185:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
185 | for(int i = 0; i < _r.size(); ++i)
| ~~^~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
524 KB |
Output is correct |
2 |
Correct |
1 ms |
492 KB |
Output is correct |
3 |
Correct |
1 ms |
492 KB |
Output is correct |
4 |
Correct |
1 ms |
492 KB |
Output is correct |
5 |
Correct |
1 ms |
508 KB |
Output is correct |
6 |
Correct |
70 ms |
3436 KB |
Output is correct |
7 |
Incorrect |
139 ms |
7552 KB |
Output isn't correct |
8 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
492 KB |
Output is correct |
2 |
Correct |
1 ms |
492 KB |
Output is correct |
3 |
Correct |
1 ms |
492 KB |
Output is correct |
4 |
Correct |
1 ms |
492 KB |
Output is correct |
5 |
Correct |
1 ms |
620 KB |
Output is correct |
6 |
Correct |
5 ms |
896 KB |
Output is correct |
7 |
Correct |
88 ms |
4588 KB |
Output is correct |
8 |
Correct |
4 ms |
748 KB |
Output is correct |
9 |
Correct |
5 ms |
876 KB |
Output is correct |
10 |
Correct |
83 ms |
6508 KB |
Output is correct |
11 |
Correct |
82 ms |
6380 KB |
Output is correct |
12 |
Correct |
76 ms |
6528 KB |
Output is correct |
13 |
Correct |
82 ms |
6656 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
492 KB |
Output is correct |
2 |
Correct |
1 ms |
492 KB |
Output is correct |
3 |
Correct |
1 ms |
492 KB |
Output is correct |
4 |
Correct |
1 ms |
492 KB |
Output is correct |
5 |
Correct |
1 ms |
620 KB |
Output is correct |
6 |
Correct |
5 ms |
896 KB |
Output is correct |
7 |
Correct |
88 ms |
4588 KB |
Output is correct |
8 |
Correct |
4 ms |
748 KB |
Output is correct |
9 |
Correct |
5 ms |
876 KB |
Output is correct |
10 |
Correct |
83 ms |
6508 KB |
Output is correct |
11 |
Correct |
82 ms |
6380 KB |
Output is correct |
12 |
Correct |
76 ms |
6528 KB |
Output is correct |
13 |
Correct |
82 ms |
6656 KB |
Output is correct |
14 |
Correct |
157 ms |
10216 KB |
Output is correct |
15 |
Correct |
1532 ms |
51860 KB |
Output is correct |
16 |
Correct |
155 ms |
10476 KB |
Output is correct |
17 |
Correct |
1476 ms |
51724 KB |
Output is correct |
18 |
Correct |
879 ms |
50220 KB |
Output is correct |
19 |
Correct |
742 ms |
50628 KB |
Output is correct |
20 |
Correct |
1479 ms |
55556 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
492 KB |
Output is correct |
2 |
Correct |
1 ms |
492 KB |
Output is correct |
3 |
Incorrect |
97 ms |
3692 KB |
Output isn't correct |
4 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
492 KB |
Output is correct |
2 |
Correct |
1 ms |
492 KB |
Output is correct |
3 |
Correct |
1 ms |
492 KB |
Output is correct |
4 |
Correct |
1 ms |
492 KB |
Output is correct |
5 |
Incorrect |
1 ms |
492 KB |
Output isn't correct |
6 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
492 KB |
Output is correct |
2 |
Correct |
1 ms |
492 KB |
Output is correct |
3 |
Correct |
1 ms |
492 KB |
Output is correct |
4 |
Correct |
1 ms |
492 KB |
Output is correct |
5 |
Incorrect |
4 ms |
748 KB |
Output isn't correct |
6 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
524 KB |
Output is correct |
2 |
Correct |
1 ms |
492 KB |
Output is correct |
3 |
Correct |
1 ms |
492 KB |
Output is correct |
4 |
Correct |
1 ms |
492 KB |
Output is correct |
5 |
Correct |
1 ms |
508 KB |
Output is correct |
6 |
Correct |
70 ms |
3436 KB |
Output is correct |
7 |
Incorrect |
139 ms |
7552 KB |
Output isn't correct |
8 |
Halted |
0 ms |
0 KB |
- |