Submission #859226

#TimeUsernameProblemLanguageResultExecution timeMemory
859226abcvuitunggioThe Big Prize (IOI17_prize)C++17
97.69 / 100
33 ms11060 KiB
#include "prize.h" #include <bits/stdc++.h> using namespace std; vector <int> a[200000]; int ch[200000],st[800001],f[200001]; void build(int node, int l, int r){ st[node]=r-l+1; if (l==r) return; int mid=(l+r)>>1; build(node<<1,l,mid); build(node<<1|1,mid+1,r); } void update(int node, int l, int r, int i){ if (l>i||r<i) return; if (l==r){ st[node]=0; return; } int mid=(l+r)>>1; update(node<<1,l,mid,i); update(node<<1|1,mid+1,r,i); st[node]=st[node<<1]+st[node<<1|1]; } int get(int node, int l, int r, int u, int v){ if (l>v||r<u||l>r) return 0; if (l>=u&&r<=v) return st[node]; int mid=(l+r)>>1; return get(node<<1,l,mid,u,v)+get(node<<1|1,mid+1,r,u,v); } int get(int node, int l, int r, int x){ if (l==r) return l; int mid=(l+r)>>1; return (st[node<<1]>=x?get(node<<1,l,mid,x):get(node<<1|1,mid+1,r,x-st[node<<1])); } void query(int i){ if (a[i].empty()) a[i]=ask(i); } void update(int i){ i++; for (;i<=200000;i+=i&(-i)) f[i]++; } int get(int i){ i++; int res=0; for (;i;i-=i&(-i)) res+=f[i]; return res; } int find_best(int n){ if (n<=5000) for (int i=0;i<n;i++){ query(i); if (!a[i][0]&&!a[i][1]) return i; } int mx=0; build(1,0,n-1); for (int i=0;i<472;i++){ query(i); update(1,0,n-1,i); if (!a[i][0]&&!a[i][1]) return i; mx=max(mx,a[i][0]+a[i][1]); } int cur=471; for (int i=0;i<472;i++) if (a[i][0]+a[i][1]!=mx) update(i); priority_queue <int, vector <int>, greater <int>> q; while (true){ while (!q.empty()){ if (a[q.top()][0]==get(q.top())){ cur=q.top(); q.pop(); } else break; } vector <int> ve; int l=1,r=get(1,0,n-1,cur,(q.empty()?n-1:q.top()-1)),val=get(1,0,n-1,0,cur-1); if (!q.empty()&&q.top()-cur-1==a[q.top()][0]-a[cur][0]){ int cnt=r,cur2=cur; while (cnt){ ve.clear(); l=1,r=cnt,val=get(1,0,n-1,0,cur2); while (l<=r){ int mid=(l+r)>>1; int pos=get(1,0,n-1,val+mid); query(pos); ve.push_back(pos); if (!a[pos][0]&&!a[pos][1]) return pos; if (a[pos]==a[cur2]){ for (int i=cur2+1;i<pos;i++) ve.push_back(i); cur2=pos-1; break; } r=mid-1; } cur2++; cnt-=ve.size(); for (int i:ve){ update(1,0,n-1,i); update(i); } } continue; } while (l<=r){ int mid=(l+r)>>1; int pos=get(1,0,n-1,val+mid); query(pos); ve.push_back(pos); if (!a[pos][0]&&!a[pos][1]) return pos; if (a[pos][0]+a[pos][1]==mx){ if (a[pos][0]>get(pos)){ if (!ch[pos]) q.push(pos); ch[pos]=1; r=mid-1; } else{ cur=pos; break; } continue; } update(pos); break; } for (int i:ve) update(1,0,n-1,i); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...