Submission #756023

#TimeUsernameProblemLanguageResultExecution timeMemory
756023Noble_MushtakJousting tournament (IOI12_tournament)C++14
100 / 100
420 ms34784 KiB
//replace Ofast with O3 for floating-point accuracy #pragma GCC optimize("Ofast,unroll-loops") #pragma GCC target("avx2,popcnt,lzcnt,abm,bmi,bmi2,fma") #include <bits/stdc++.h> using num = int64_t; using namespace std; #define rep(i, a, b) for(num i = a; i < (b); ++i) #define REPI(t, n) for (num t = 0; t < n; ++t) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() using ll = long long; using pii = pair<int, int>; using vi = vector<int>; #ifdef TESTING #define DEBUG(...) __VA_ARGS__ #else #define DEBUG(...) #endif #include <bits/extc++.h> /** keep-include */ using namespace __gnu_pbds; template<class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; //insert(k) inserts item k //find_by_order(k) returns an iterator to the element which is bigger than k items //order_of_key(k) returns number of items < k vector<vi> treeJump(vi& P){ int on = 1, d = 1; while(on < sz(P)) on *= 2, d++; vector<vi> jmp(d, P); rep(i,1,d) rep(j,0,sz(P)) jmp[i][j] = jmp[i-1][jmp[i-1][j]]; return jmp; } int jmp(vector<vi>& tbl, int nod, int steps){ rep(i,0,sz(tbl)) if(steps&(1<<i)) nod = tbl[i][nod]; return nod; } int GetBestPosition(int N, int C, int R, int *K, int *S, int *E) { num treeSz = N+C; vector<num> initVals(N); initVals[C] = R; REPI(i, N-1) initVals[i+1] = K[i]; vi par(treeSz); vector<vector<num>> children(treeSz); vector<pair<num,num>> intervals(treeSz); Tree<pair<num,num>> curOrder; REPI(i, N) { curOrder.insert({i, C+i}); intervals[C+i] = {i,i}; } REPI(i, C) { num newIdx = -1; num curV = C-i-1; num st = S[i]; num nd = E[i]; while (st <= nd) { auto it = curOrder.find_by_order(st); if (newIdx == -1) { newIdx = it->first; intervals[curV] = intervals[it->second]; } else { intervals[curV].second = intervals[it->second].second; } children[curV].push_back(it->second); par[it->second] = curV; curOrder.erase(it); --nd; } assert(newIdx != -1); curOrder.insert({newIdx, curV}); } auto tbl = treeJump(par); vector<num> segtree(2*N); REPI(i, N) segtree[N+i] = initVals[i]; for (num i = N-1; i >= 1; --i) segtree[i] = max(segtree[2*i], segtree[2*i+1]); auto update = [&](num idx, num y) { num curIdx = idx+N; segtree[curIdx] = y; while (curIdx > 1) { curIdx >>= 1; segtree[curIdx] = max(segtree[2*curIdx], segtree[2*curIdx+1]); } }; auto query = [&](num idx1, num idx2) { num leftIdx = idx1+N, rightIdx = idx2+N+1; num ans = 0; while (leftIdx < rightIdx) { if (leftIdx & 1) ans = max(ans, segtree[leftIdx]), ++leftIdx; if (rightIdx & 1) --rightIdx, ans = max(ans, segtree[rightIdx]); leftIdx >>= 1, rightIdx >>= 1; } return ans; }; num roundsWon = 0, bestPos = 0; REPI(i, N) { if (i > 0) { update(i-1, K[i-1]); update(i, R); } num leftAns = 0, rightAns = C; while (leftAns < rightAns) { num mid = (leftAns+rightAns+1)/2; num curAns = jmp(tbl, C+i, mid); if (query(intervals[curAns].first, intervals[curAns].second) == R) leftAns = mid; else rightAns = mid-1; } if (leftAns > roundsWon) { roundsWon = leftAns; bestPos = i; } //cout << leftAns << " " << i << " | " << roundsWon << " " << bestPos << "\n"; } return bestPos; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...