This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "plants.h"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct E {
ll x = 1e15, lz=0;
E(){};
E(ll xx){x=xx;};
friend E operator+(E a, E b){
return min(a.x, b.x);
}
void aply(ll add){
x+=add;
lz+=add;
}
};
struct node{
int lb, rb;
E x;
node *l=nullptr, *r=nullptr;
bool ext(){
if(lb<rb and not l){
int mb = (lb + rb) / 2;
l = new node{lb, mb}, r = new node{mb+1, rb};
}
// push
if(l){
l->x.aply(x.lz);
r->x.aply(x.lz);
x.lz=0;
}
return l;
}
E qry(int lo, int hi){
if(hi<lb or rb<lo) return E();
if(lo<=lb and rb<=hi) return x;
if(ext()) {
E y = l->qry(lo, hi) + r->qry(lo, hi);
return y;
}
return E();
}
void upd(int lo, int hi, ll add){
if(hi<lb or rb<lo) return;
if(lo<=lb and rb<=hi) {
x.aply(add);
return;
}
if(ext()) {
l->upd(lo, hi, add), r->upd(lo, hi, add);
x = l->x + r->x;
}
}
void bld(vector<int> &v){
if(lb==rb) x.x = v[lb];
if(ext()) {
l->bld(v), r->bld(v);
x = l->x + r->x;
}
}
};
vector<int> h;
vector<vector<int>> jl, jr;
int K;
void init(int k, std::vector<int> r) {
K = k;
int n = r.size(), t=n;
node seg{0, n-1};
seg.bld(r);
h.assign(n, 0);
auto find = [&](int lb, int rb){
while(lb<rb){
int mb = (lb+rb+1)/2;
if(seg.qry(mb, rb).x==0){
lb=mb;
}else{
rb=mb-1;
}
}
return seg.qry(lb, lb).x==0 ? lb : int(-1e9);
};
function<void(int)> get = [&](int id){
// find 0 in range (id-k+1, id-1)
// if (id-k+1)<0
int lb = id - k + 1, rb = id-1;
while(1){
int nid = -1e9;
if(rb>=0){
nid = max(nid, find(max(lb, 0), rb));
}if(lb<0 and nid<0){
nid=max(nid, find((lb+n)%n, n-1));
}
if(nid>=0)
get(nid);
else
break;
}
if(rb>=0){
seg.upd(max(lb, 0), rb, -1);
}if(lb<0){
seg.upd((lb+n)%n, n-1, -1);
}
seg.upd(id, id, 1e9);
h[id]=t--;
};
while(find(0, n-1)>=0){
//cerr << find(0, n-1) << endl;
get(find(0, n-1));
//for(int i=0; i<n; i++) cerr << seg.qry(i, i).x << " "; cout << endl;
}
//for(auto x:h) cerr << x-1 << " "; cerr<<endl;
node best{0, n-1};
vector<int> pos(n+1);
for(int i=0; i<n; i++) pos[h[i]] = i;
auto findbest = [&](int lb, int rb){
// TODO: check query outside the tree
ll cur = best.qry(lb, rb).x;
if(rb>=n) {
cur = min(cur, best.qry(0, rb%n).x);
}if(lb<0){
cur=min(cur, best.qry((lb+n)%n, n-1).x);
}
return cur;
};
jl.assign(n, vector<int>(20));
jr.assign(n, vector<int>(20));
for(int i=n; i>0; i--){
ll r = findbest(pos[i]+1, pos[i]+k-1);
ll l = findbest(pos[i]-k+1, pos[i]-1);
if(r>n) jr[pos[i]][0] = pos[i];
else jr[pos[i]][0] = pos[r];
if(l>n) jl[pos[i]][0] = pos[i];
else jl[pos[i]][0] = pos[l];
best.upd(pos[i], pos[i], -1e15 + i);
}
for(auto y:h) cerr << y-1 << " "; cerr << endl;
for(int i=0; i<n; i++) cerr << jr[i][0] << " "; cerr << endl;
for(int i=0; i<n; i++) cerr << jl[i][0] << " "; cerr << endl;
for(int k=1; k<20; k++){
for(int i=0; i<n; i++){
jl[i][k] = jl[jl[i][k-1]][k-1];
jr[i][k] = jr[jr[i][k-1]][k-1];
}
}
}
int compare_plants(int x, int y) {
// go from x to y right
int mul = 1;
if(x>y){
mul=-1;
swap(x, y);
}
int ans = 0;
int xx = x;
for(int i=19; i>=0; i--){
if(jr[xx][i]<y and jr[xx][i]>x){
xx=jr[xx][i];
}
}
if(xx < y and y<xx+K and h[xx]<h[y]){
ans=-1;
}
int yy = y;
for(int i=19; i>=0; i--){
if(x < jl[yy][i] and jl[yy][i]<y){
yy=jl[yy][i];
}
}
if(yy - K < x and x < yy and h[x] > h[yy]){
ans=1;
}
yy = y;
for(int i=19; i>=0; i--){
if(y < jr[yy][i] or jr[yy][i] < x){
yy=jr[yy][i];
}
}
if(((yy < x and x < yy + K) or (x < yy and yy + K >= h.size() and x < (yy + K) % h.size())) and h[yy] < h[x]){
ans=1;
}
xx = x;
for(int i=19; i>=0; i--){
if(jl[xx][i]<x or y<jl[xx][i]){
xx = jl[xx][i];
}
}
if(((y < xx and xx - K < y) or (xx < y and xx-K < 0 and (xx-K+int(h.size())) % h.size() < y)) and h[y]>h[xx]){
ans=-1;
}
return ans * mul;
}
Compilation message (stderr)
plants.cpp: In function 'void init(int, std::vector<int>)':
plants.cpp:146:2: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
146 | for(auto y:h) cerr << y-1 << " "; cerr << endl;
| ^~~
plants.cpp:146:36: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
146 | for(auto y:h) cerr << y-1 << " "; cerr << endl;
| ^~~~
plants.cpp:147:2: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
147 | for(int i=0; i<n; i++) cerr << jr[i][0] << " "; cerr << endl;
| ^~~
plants.cpp:147:50: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
147 | for(int i=0; i<n; i++) cerr << jr[i][0] << " "; cerr << endl;
| ^~~~
plants.cpp:148:2: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
148 | for(int i=0; i<n; i++) cerr << jl[i][0] << " "; cerr << endl;
| ^~~
plants.cpp:148:50: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
148 | for(int i=0; i<n; i++) cerr << jl[i][0] << " "; cerr << endl;
| ^~~~
plants.cpp: In function 'int compare_plants(int, int)':
plants.cpp:191:52: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
191 | if(((yy < x and x < yy + K) or (x < yy and yy + K >= h.size() and x < (yy + K) % h.size())) and h[yy] < h[x]){
| ~~~~~~~^~~~~~~~~~~
plants.cpp:191:70: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
191 | if(((yy < x and x < yy + K) or (x < yy and yy + K >= h.size() and x < (yy + K) % h.size())) and h[yy] < h[x]){
| ~~^~~~~~~~~~~~~~~~~~~~~
plants.cpp:201:90: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
201 | if(((y < xx and xx - K < y) or (xx < y and xx-K < 0 and (xx-K+int(h.size())) % h.size() < y)) and h[y]>h[xx]){
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |