Submission #608431

#TimeUsernameProblemLanguageResultExecution timeMemory
608431balbitTeams (IOI15_teams)C++14
100 / 100
1822 ms329932 KiB
#include "teams.h" #include <bits/stdc++.h> #pragma GCC optimize("O3") using namespace std; // #undef BALBIT // #define int ll #define ll long long #define pii pair<int, int> #define f first #define s second #define FOR(i,a,b) for (int i = a; i<b; ++i) #define REP(i,n) FOR(i,0,n) #define REP1(i,n) FOR(i,1,n+1) #define MX(a,b) a = max(a,b) #define MN(a,b) a = min(a,b) #define SZ(x) (int)((x).size()) #define ALL(x) (x).begin(), (x).end() #define pb push_back #ifdef BALBIT #define bug(...) cerr<<"#"<<__LINE__<<":"<<#__VA_ARGS__<<"- ", _do(__VA_ARGS__) template<typename T> void _do(T && x) {cerr<<x<<endl;} template<typename T, typename ...S> void _do(T && x, S && ...y) {cerr<<x<<", "; _do(y...);} #else #define bug(...) #define endl '\n' #endif namespace { const int maxn = 5e5+10; const ll inf = 0x3f3f3f3f3f3f3f3f; const int BA= 40; } int N; vector<pii> seg; namespace MAO{ int lc[maxn*BA], rc[maxn*BA], val[maxn*BA]; int history[maxn]; int IT = 1; int MO(int p, int o, int l, int r) { if (l > p || r < p) return o; int NO = ++IT; val[NO] = val[o] + 1; if (l == r) { return NO; } int mid = (l+r)/2; lc[NO] = MO(p,lc[o],l,mid); rc[NO] = MO(p,rc[o],mid+1,r); return NO; } int build(int l, int r) { int NO = ++IT; if (l == r) { return NO; } int mid = (l+r)/2; lc[NO] = build(l,mid); rc[NO] = build(mid+1,r); return NO; } int yeah[maxn*BA]; vector<int> yoo; int QU(int L, int R, int o, int l, int r) { // bug(p,l,r,o,val[o]); if (~yeah[o]) return yeah[o]; if (l > R || r < L) return 0; if (l >= L && r <= R) { return val[o]; } int mid = (l+r) >> 1; yoo.pb(o); return yeah[o] = QU(L,R,lc[o],l,mid) + QU(L,R,rc[o],mid+1,r); } int QUsimple(int L, int R, int o, int l, int r) { // bug(p,l,r,o,val[o]); if (l > R || r < L) return 0; if (l >= L && r <= R) { return val[o]; } int mid = (l+r) >> 1; return QUsimple(L,R,lc[o],l,mid) + QUsimple(L,R,rc[o],mid+1,r); } } inline int get(int L, int Ra, int Rb, bool rep=0) { // temporary function // returns the number of segments with index >= L && right value >= R // to be replaced by segtree later // int re = 0; // for(int i = L; i<N; ++i) { // if(seg[i].s >= R) re++; // } // return re; if (L >= N || Ra > N || Ra-1 > Rb) return 0; // bug(L,R); MX(L, 0); int ret = rep?MAO::QU(Ra-1, Rb-1,MAO::history[L],0,N-1) : MAO::QUsimple(Ra-1, Rb-1,MAO::history[L],0,N-1); return ret; } void init(signed NN, signed A[], signed B[]) { memset(MAO::lc, -1, sizeof MAO::lc); memset(MAO::rc, -1, sizeof MAO::rc); memset(MAO::yeah, -1, sizeof MAO::yeah); memset(MAO::val, 0, sizeof MAO::val); N = NN; seg.clear(); REP(i,N) { seg.pb({A[i], B[i]}); } sort(ALL(seg)); REP(i, N)bug(i,seg[i].f,seg[i].s); MAO::history[N] = MAO::build(0, N-1); bug(MAO::history[N]); for(int i = N-1; i>=0; --i) { MAO::history[i] = MAO::MO(seg[i].s-1,MAO::history[i+1],0,N-1); } // bug(MAO::QU(0,MAO::history[0],0,N-1)); // bug(MAO::QU(1,MAO::history[0],0,N-1)); // bug(MAO::QU(2,MAO::history[0],0,N-1)); // bug(MAO::QU(3,MAO::history[0],0,N-1)); } struct item{ int L, R; }; signed can(signed M, signed K[]) { bug(M); map<int, int> take; REP(i,M) { take[K[i]]+=K[i]; if (take[K[i]] > N) return 0; } vector<pii> tmp; for(pii p :take) { tmp.pb(p); } sort(ALL(tmp), greater<pii>()); vector<item > stk; // {L, R} stk.pb({-1, N+1}); int goback = N; for (auto PPP :tmp) { int R = PPP.f; int need = PPP.s; { int bl = 0, br = goback; while (bl != br) { int mid = (bl + br) / 2; if(seg[mid].f > R) { br = mid; }else{ bl = mid+1; } } goback = bl; } // while(goback-1 >= 0 && seg[goback-1].f > R) --goback; int lastl = goback; while (!stk.empty()) { int sL = stk.back().L, sR = stk.back().R; if (sL >= lastl) { stk.pop_back(); continue; } // indicates that, of all segments of index in [sL, lastl), // anything with right value >= sR was taken int prv = lastl; lastl = sL; int haverem = +get(sL, R, sR-1) -get(prv, R, sR-1); // (get(sL,R) - get(prv,R)) - (get(sL,sR) - get(prv, sR)); bug(haverem); if (haverem < need) { need -= haverem; stk.pop_back(); continue; }else if (haverem == need) { bug(haverem, need); need -= haverem; stk.back().R = R; break; }else{ bug(need); int bl = sL + 1, br = prv - need; for (int e : MAO::yoo) { MAO::yeah[e] = -1; } MAO::yoo.clear(); int fix = -get(prv, R,sR-1); // { // int yar = fix +get(br, R, sR-1); // if(yar == need) { // bl = br; // } // } while (bl != br) { int mid = (bl +br) / 2; int yum = fix + get(mid, R, sR-1,1) ; bug(bl, br, mid, yum); bug(prv, sR, R); if (yum == need){ bl = br = mid; break; } if(yum > need) { bl = mid+(yum-need); }else{ br = mid-(need-yum); } } bug("add", bl, R); stk.push_back({bl, R}); break; } } if(stk.empty()) return 0; } bug("yay"); return 1; } /* 8 1 4 2 3 2 3 2 3 2 3 2 4 2 4 2 4 1 3 2 3 4 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...