Submission #793479

#TimeUsernameProblemLanguageResultExecution timeMemory
793479Username4132Teams (IOI15_teams)C++14
100 / 100
1632 ms387568 KiB
#include "teams.h" #include<iostream> #include<vector> #include<algorithm> #include<cassert> using namespace std; using pii = pair<int, int>; #define forn(i, n) for(int i=0; i<(int)n; ++i) #define forsn(i, s, n) for(int i=s; i<(int)n; ++i) #define PB push_back #define F first #define S second struct Vertex{ int value; Vertex *l, *r; Vertex(int _value) : value(_value), l(NULL), r(NULL) {} Vertex(Vertex* _l, Vertex* _r) : value(_l->value + _r->value), l(_l), r(_r) {} }; Vertex* build(int tl, int tr){ if(tl==tr) return new Vertex(0); int tm = (tl+tr)>>1; return new Vertex(build(tl, tm), build(tm+1, tr)); } Vertex* update(Vertex* v, int tl, int tr, int pos, int delta){ if(tl==tr) return new Vertex(v->value + delta); int tm = (tl+tr)>>1; if(pos<=tm) return new Vertex(update(v->l, tl, tm, pos, delta), v->r); else return new Vertex(v->l, update(v->r, tm+1, tr, pos, delta)); } int query(Vertex* v, int l, int r, int tl, int tr){ if(l>r) return 0; if(l==tl && r==tr) return v->value; int tm = (tl+tr)>>1; return query(v->l, l, min(r, tm), tl, tm) + query(v->r, max(l, tm+1), r, tm+1, tr); } pii srch(Vertex* vl, Vertex* vr, int tl, int tr, int target){ assert(target>0); if(tl==tr) return {tl, target}; int tm = (tl+tr)>>1; int sum = vr->l->value - vl->l->value; if(sum < target) return srch(vl->r, vr->r, tm+1, tr, target-sum); else return srch(vl->l, vr->l, tl, tm, target); } const int MAXN = 500010; int n; Vertex* roots[MAXN]; vector<int> vals[MAXN]; void init(int N, int A[], int B[]) { n=N; roots[0]=build(0, n+4); forn(i, n) vals[A[i]].PB(B[i]); forsn(i, 1, n+1){ roots[i]=roots[i-1]; for(int el:vals[i]) roots[i]=update(roots[i], 0, n+4, el, 1); } } int cou(int x1, int x2, int y1, int y2){ return query(roots[max(x2-1, 0)], y1, y2-1, 0, n+4) - query(roots[max(x1-1, 0)], y1, y2-1, 0, n+4); } pii binary(int x1, int x2, int bound){ return srch(roots[max(x1-1, 0)], roots[max(x2-1, 0)], 0, n+4, bound); } bool solve(vector<pii>& dom, vector<int>& xt, pii ins, int target){ int del=0; while(ins.S >= dom.back().S){ if(ins.S == dom.back().S) del=xt.back(); dom.pop_back(); xt.pop_back(); } while(true){ int obt = cou(dom.back().F + 1, ins.F + 1, ins.S, dom.back().S) - del; if(obt < target){ target-=obt; ins.S=dom.back().S; del=xt.back(); dom.pop_back(); xt.pop_back(); } else{ int base = cou(dom.back().F + 1, ins.F + 1, 0, ins.S) + del; pii res = binary(dom.back().F + 1, ins.F + 1, target + base); dom.PB({ins.F, res.F}); xt.PB(res.S); return true; } if(dom.empty()) return false; } } int can(int m, int arr[]) { int dummy=0; forn(i, m){ dummy+=arr[i]; if(dummy>n) return 0; } sort(arr, arr+m); vector<pii> dom; vector<int> xt; dom.PB({-1, n+2}); xt.PB(0); int cnt=0; forn(i, m){ ++cnt; if(i==m-1 || arr[i]!=arr[i+1]){ if(!solve(dom, xt, {arr[i], arr[i]}, cnt*arr[i])){ return 0; } cnt=0; } } return 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...