Submission #1171843

#TimeUsernameProblemLanguageResultExecution timeMemory
1171843Math4Life2020Distributing Candies (IOI21_candies)C++20
100 / 100
2288 ms43532 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<ll,ll>; const ll INF = 1e18; inline pii fzmax(pii p1, pii p2) { if (p1.first>p2.first) { return p1; } return p2; } inline pii fzmin(pii p1, pii p2) { if (p1.first<p2.first) { return p1; } return p2; } inline ll v2(ll x) { return __builtin_ctz(x); } const ll Nm = 262144; const ll E = 18; ll minv[2*Nm]; ll minl[2*Nm]; ll maxv[2*Nm]; ll maxl[2*Nm]; ll lz[2*Nm]; //ALREADY APPLIED void init() { for (ll i=0;i<(2*Nm);i++) { minv[i]=0; maxv[i]=0; lz[i]=0; } for (ll i=0;i<Nm;i++) { minl[i+Nm]=i; maxl[i+Nm]=i; } for (ll p=(Nm-1);p>=1;p--) { minl[p]=minl[2*p]; maxl[p]=maxl[2*p]; } } void lft(ll p0) { if (p0==0) { return; } assert(lz[p0]==0); //cout << "lz[p0="<<p0<<"]="<<lz[p0]<<"\n"; if (p0<Nm) { if (minv[2*p0]<minv[2*p0+1]) { minv[p0]=minv[2*p0]; minl[p0]=minl[2*p0]; } else { minv[p0]=minv[2*p0+1]; minl[p0]=minl[2*p0+1]; } if (maxv[2*p0]>maxv[2*p0+1]) { maxv[p0]=maxv[2*p0]; maxl[p0]=maxl[2*p0]; } else { maxv[p0]=maxv[2*p0+1]; maxl[p0]=maxl[2*p0+1]; } } } void lftP(ll p0) { for (ll e=1;e<=E;e++) { if ((p0>>e)>0) { //cout << "lifting at "<<(p0>>e) << "\n"; lft(p0>>e); // if (1) { // cout << "maxv="<<maxv[p0>>e]<<", maxl="<<maxl[p0>>e]<<"\n"; // cout << "minv="<<minv[p0>>e]<<", minl="<<minl[p0>>e]<<"\n"; // } } } } void pdn(ll p0) { if (lz[p0]!=0) { if (p0<Nm) { lz[2*p0]+=lz[p0]; minv[2*p0]+=lz[p0]; maxv[2*p0]+=lz[p0]; lz[2*p0+1]+=lz[p0]; minv[2*p0+1]+=lz[p0]; maxv[2*p0+1]+=lz[p0]; } lz[p0]=0; } } void pdnP(ll p0) { for (ll e=E;e>=0;e--) { if (p0>>e) { pdn(p0>>e); } } } void upd1(ll v0, ll p0) { pdnP(p0); lz[p0]+=v0; minv[p0]+=v0; maxv[p0]+=v0; lftP(p0); } void upd0(ll v0, ll x0) { if (x0>=Nm) { return; } assert(x0<Nm); ll vx = v2(Nm-x0); upd1(v0,(1LL<<(E-vx))+(x0>>vx)); upd0(v0,x0+(1LL<<vx)); } pii qrymax(ll a, ll b) { //{value, location} if (a>b) { return {-INF,-1}; } ll va = v2(a); ll vb = v2(b+1); if (va<vb) { ll pc = (a>>va)+(1<<(E-va)); pdnP(pc); //cout << "pc="<<pc<<"\n"; //cout << "max vals: "<<maxv[pc]<<","<<maxl[pc]<<"\n"; return fzmax({maxv[pc],maxl[pc]},qrymax(a+(1<<va),b)); } else { ll pc = (b>>vb)+(1<<(E-vb)); pdnP(pc); //cout << "pc="<<pc<<"\n"; //cout << "max vals: "<<maxv[pc]<<","<<maxl[pc]<<"\n"; return fzmax({maxv[pc],maxl[pc]},qrymax(a,b-(1<<vb))); } } pii qrymin(ll a, ll b) { if (a>b) { return {INF,-1}; } ll va = v2(a); ll vb = v2(b+1); if (va<vb) { ll pc = (a>>va)+(1<<(E-va)); pdnP(pc); //cout << "pc="<<pc<<"\n"; //cout << "min vals: "<<minv[pc]<<","<<minl[pc]<<"\n"; return fzmin({minv[pc],minl[pc]},qrymin(a+(1<<va),b)); } else { ll pc = (b>>vb)+(1<<(E-vb)); pdnP(pc); //cout << "pc="<<pc<<"\n"; //cout << "min vals: "<<minv[pc]<<","<<minl[pc]<<"\n"; return fzmin({minv[pc],minl[pc]},qrymin(a,b-(1<<vb))); } } ll qry0(ll c0) { //cout << "querying c0="<<c0<<"\n"; ll xmin = -1; ll xmax = Nm-1; while (xmin!=xmax) { ll xtest = (xmin+xmax+1)/2; //cout << "xtest="<<xtest<<"\n"; pii p1 = qrymin(xtest,Nm-1); //cout << "p1="<<p1.first<<","<<p1.second<<"\n"; pii p2 = qrymax(xtest,Nm-1); //cout << "p2="<<p2.first<<","<<p2.second<<"\n"; if (abs(p1.first-p2.first)>=c0) { xmin = xtest; } else { xmax = xtest-1; } } //cout << "xmin="<<xmin<<"\n"; if (xmin==-1) { //return qrymax(Nm-1,Nm-1).first; ll v1 = qrymin(0,Nm-1).first; ll vf = qrymax(Nm-1,Nm-1).first; return (vf-v1); } else { pii p1 = qrymin(xmin,Nm-1); //cout << "p1="<<p1.first<<","<<p1.second<<"\n"; pii p2 = qrymax(xmin,Nm-1); //cout << "p2="<<p2.first<<","<<p2.second<<"\n"; ll vf = qrymax(Nm-1,Nm-1).first; //cout << "vf="<<vf<<"\n"; if (p1.second>p2.second) { //min comes last return (vf-p1.first); } else { return (c0-p2.first+vf); } } } vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) { init(); ll N = c.size(); ll Q = l.size(); vector<pii> updV[N+1]; //store: {value to change by, starting index of update} for (ll q=0;q<Q;q++) { updV[l[q]].push_back({v[q],q+1}); updV[r[q]+1].push_back({-v[q],q+1}); } vector<int> ans; for (ll x=0;x<N;x++) { for (pii p0: updV[x]) { upd0(p0.first,p0.second); } ll ans1 = qry0(c[x]); //cout << ans1 << "\n"; ans.push_back(ans1); } return ans; }
#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...