Submission #1030329

#TimeUsernameProblemLanguageResultExecution timeMemory
1030329hotboy2703Comparing Plants (IOI20_plants)C++17
100 / 100
1078 ms161956 KiB
#include "plants.h" #include<bits/stdc++.h> using namespace std; using ll = long long; #define pll pair <ll,ll> #define fi first #define se second #define MP make_pair #define sz(a) (ll((a).size())) #define BIT(mask,i) (((mask) >> (i))&1) #define MASK(i) (1LL<<(i)) namespace trung{ const ll MAXN = 2e5+100; const ll INF = 1e9+7; ll n,k; vector <int> val; namespace seg{ pll tree[MAXN*4]; ll lazy[MAXN*4]; pll combine(pll x,pll y){ if (x.fi > y.fi)return y; else return x; } void build(ll id=1,ll l=0,ll r=n-1){ if (l==r){tree[id] = MP(val[l],l);} else{ ll mid = (l + r) >> 1; build(id<<1,l,mid); build(id<<1|1,mid+1,r); tree[id] = combine(tree[id<<1],tree[id<<1|1]); } } void push(ll id,ll x){ tree[id].fi+=x; lazy[id]+=x; } void lz(ll id){ push(id<<1,lazy[id]); push(id<<1|1,lazy[id]); lazy[id] = 0; } void update(ll l1,ll r1,ll id=1,ll l=0,ll r=n-1){ // if (id==1)cout<<"UPD "<<l1<<' '<<r1<<endl; if (l1 > r || l > r1 || l1 > r1)return; if (l1 <= l && r <= r1){ // cout<<"UPD2 "<<l<<' '<<r<<endl; push(id,-1); return; } lz(id); ll mid = (l + r) >> 1; update(l1,r1,id<<1,l,mid); update(l1,r1,id<<1|1,mid+1,r); tree[id] = combine(tree[id<<1],tree[id<<1|1]); } void del(ll i,ll id=1,ll l=0,ll r=n-1){ if (l > i || i > r)return; if (l==r){ // cout<<"BRUH "<<i<<endl; tree[id].fi = INF; return; } lz(id); ll mid = (l + r) >> 1; del(i,id<<1,l,mid); del(i,id<<1|1,mid+1,r); tree[id] = combine(tree[id<<1],tree[id<<1|1]); } ll get(ll l1,ll r1,ll id=1,ll l=0,ll r=n-1){ if (l1 > r || l > r1 || l1 > r1)return n+1; if (tree[id].fi!=0)return n+1; if (l1 <= l && r <= r1)return tree[id].se; lz(id); ll mid = (l + r) >> 1; ll res = get(l1,r1,id<<1,l,mid); if (res==n+1)res = get(l1,r1,id<<1|1,mid+1,r); return res; } ll sus(ll i,ll id=1,ll l=0,ll r=n-1){ if (i > r || l > i)return INF+1; if (l == r)return tree[id].fi; lz(id); ll mid = (l + r) >> 1; return min(sus(i,id<<1,l,mid),sus(i,id<<1|1,mid+1,r)); } } vector <ll> h; ll label; bool in[MAXN]; void solve(ll x){ // assert(in[x] == 0); // in[x] = 1; ll l = x-k+1,r=x-1; // cout<<x<<' '<<l<<' '<<r<<endl; ll tmp; while ((tmp=seg::get(l,r)) != n+1){ solve(tmp); } while ((tmp=seg::get(l+n,r+n)) != n+1){ // cout<<x<<' '<<tmp<<endl; solve(tmp); } seg::del(x); h[x] = --label; seg::update(l,r); seg::update(l+n,r+n); } const ll MAXK = 20; ll sp_nxt[MAXK][MAXN*2]; ll sp_pre[MAXK][MAXN*2]; bool solve_nxt(ll x,ll y){ for (ll j = MAXK-1;j>=0;j--){ if (sp_nxt[j][x] <= y)x = sp_nxt[j][x]; } return (y-x<k&&h[y]>=h[x]); } bool solve_pre(ll x,ll y){ for (ll j = MAXK-1;j>=0;j--){ if (sp_pre[j][x] >= y)x = sp_pre[j][x]; } return (x-y<k&&h[y]>=h[x]); } } void init(int K, std::vector<int> r){ using namespace trung; val = r; n=sz(r); h.resize(n); k=K; seg::build(); // cout<<"OK"<<endl; ll cur; label = n; while ((cur=seg::get(0,n-1)) != n+1){ // cout<<"CUR "<<cur<<endl; solve(cur); } for (ll i = 0;i < n;i ++){ h.push_back(h[i]); } h.insert(h.begin(),INF); h.push_back(INF); { set <pll> s; for (ll i = 1;i <= k - 1;i ++){ s.insert(MP(h[i],i)); } for (ll i = 1;i <= 2 * n;i ++){ s.erase(MP(h[i],i)); if (i + k - 1 <= 2 * n)s.insert(MP(h[i+k-1],i+k-1)); auto tmp = s.lower_bound(MP(h[i],i)); ; if (tmp != s.end())sp_nxt[0][i] = (*tmp).se; else sp_nxt[0][i] = i; } s.clear(); for (ll i = 2*n;i>=2*n-k+2;i--)s.insert(MP(h[i],i)); for (ll i = 2*n;i >= 1;i--){ s.erase(MP(h[i],i)); if (i - k + 1 >= 1)s.insert(MP(h[i - k + 1],i - k + 1)); auto tmp = s.lower_bound(MP(h[i],i)); ; if (tmp != s.end())sp_pre[0][i] = (*tmp).se; else sp_pre[0][i] = i; } // for (ll i = 1;i <= 2 * n;i ++){ // cout<<h[i]<<' '; // } // cout<<endl; // for (ll i = 1;i <= 2 * n;i ++){ // cout<<sp_nxt[0][i]<<' '; // } // cout<<endl; // for (ll i = 1;i <= 2 * n;i ++){ // cout<<sp_pre[0][i]<<' '; // } // cout<<endl; } for (ll j = 1;j<MAXK;j ++){ for (ll i = 1;i <= 2 * n;i ++){ sp_nxt[j][i] = sp_nxt[j-1][sp_nxt[j-1][i]]; sp_pre[j][i] = sp_pre[j-1][sp_pre[j-1][i]]; } } } int compare_plants(int x, int y){ using namespace trung; x++,y++; if (h[x] > h[y]){ if (solve_nxt(y,x+n)||solve_pre(y,x))return 1; else return 0; } else{ if (solve_nxt(x,y)||solve_pre(x+n,y))return -1; else return 0; } // return (h[x] > h[y] ? 1 : -1); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...