Submission #1283642

#TimeUsernameProblemLanguageResultExecution timeMemory
1283642gustavo_d마상시합 토너먼트 (IOI12_tournament)C++17
0 / 100
0 ms332 KiB
#include <bits/stdc++.h> using namespace std; const int MAXN = 1e5; const int LOG = 20; int f[LOG+1][2*MAXN]; pair<int, int> rngs[2*MAXN]; int hsb(int x) { return 31 - __builtin_clz(x); } struct Node { int actives, rngId; Node (int _actives=0, int _rngId=-1): actives(_actives), rngId(_rngId) {} Node operator+(Node right) { Node left = *this; return Node(left.actives + right.actives); } }; struct SEG { vector<Node> seg; int n; SEG (int _n=0) { n = 1; while (n < _n) n <<= 1; seg = vector<Node> (2*n); for (int i=0; i<_n; i++) { seg[i+n] = Node(1, i); } for (int v=n-1; v>0; v--) seg[v] = seg[getLeft(v)] + seg[getRight(v)]; } int getLeft(int v) { return 2*v; } int getRight(int v) { return 2*v+1; } void put(int v, int l, int r, int i, Node val) { if (l == r) { seg[v] = val; return; } int m = (l + r) / 2; if (i <= m) put(getLeft(v), l, m, i, val); else put(getRight(v), m+1, r, i, val); seg[v] = seg[getLeft(v)] + seg[getRight(v)]; } pair<int, int> xTh(int v, int l, int r, int x) { if (l == r) { return {l, seg[v].rngId}; } int m = (l + r) / 2; if (seg[getLeft(v)].actives >= x) return xTh(getLeft(v), l, m, x); else return xTh(getRight(v), m+1, r, x - seg[getLeft(v)].actives); } }; struct SparseTable { vector<int> fl[LOG+1], fr[LOG+1]; SparseTable(vector<int> a) { int n = (int)a.size(); for (int b=0; b<=LOG; b++) { fl[b] = vector<int> (n, 0); fr[b] = vector<int> (n, 0); } for (int i=0; i<n; i++) fl[0][i] = fr[0][i] = a[i]; for (int b=1; b<=LOG; b++) { for (int i=0; i<n; i++) { if (i+1 >= (1 << b)) fl[b][i] = max(fl[b-1][i], fl[b-1][i-(1 << (b-1))]); if (n-i >= (1 << b)) fr[b][i] = max(fr[b-1][i], fr[b-1][i+(1 << (b-1))]); } } } int mx(int l, int r) { int sz = (r - l + 1); return max(fl[hsb(sz)][r], fr[hsb(sz)][l]); } }; int GetBestPosition(int N, int C, int R, int *K, int *S, int *E) { int n = N; vector<int> ranks; for (int i=0; i<n-1; i++) ranks.push_back(K[i]); SparseTable table(ranks); for (int i=0; i<n; i++) { rngs[i] = {i, i}; f[0][i] = -1; } SEG seg(n); for (int round=0, nxtRng=n; round<C; round++, nxtRng++) { int l = S[round], r = E[round]; f[0][nxtRng] = -1; for (int i=l; i<=r; i++) { auto [rngPos, rngId] = seg.xTh(1, 0, seg.n-1, l+1); seg.put(1, 0, seg.n-1, rngPos, Node(0)); f[0][rngId] = nxtRng; if (i == l) rngs[nxtRng].first = rngs[rngId].first; if (i == r) rngs[nxtRng].second = rngs[rngId].second; } seg.put(1, 0, seg.n-1, l, Node(1, nxtRng)); } // for (int i=0; i<n+C; i++) { // cout << rngs[i].first << ' ' << rngs[i].second << ' ' << f[0][i] << '\n'; // } for (int b=1; b<=LOG; b++) { for (int i=0; i<n+C; i++) { if (f[b-1][i] == -1) { f[b][i] = -1; continue; } f[b][i] = f[b-1][f[b-1][i]]; } } int bestPos = 0, mxWins = -1; for (int pos = 0; pos < n; pos++) { // cout << pos << ':' << '\n'; int wins = 0; int rng = pos; for (int b=LOG; b>=0; b--) { int newRng = f[b][rng]; if (newRng == -1) continue; auto [l, r] = rngs[newRng]; // cout << "test" << newRng << ' ' << l << ' ' << r << '=' << table.mx(l, r-1) << '\n'; if (l < r and table.mx(l, r-1) > R) continue; rng = newRng; wins += (1 << b); } // cout << wins << '\n' << '\n'; if (wins > mxWins) { mxWins = wins; bestPos = pos; } } return bestPos; } // int main() { // int x; cin >> x; // cout << hsb(x); // return 0; // }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...