This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
//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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |