meaning of the title
Sol
First of all, guess a conclusion: for each query, it must be optimal to enumerate a starting point and wait until a certain point appears before going to the next point.
It can't be proved. I took 3w group in the examination room. That's right...
First, it is convenient to enumerate the starting point by doubling the array length, and then it is a monotonous queue model. Sort it out. That's what we need
\[n - 1 + \min_{i=1}^n i + (\max_{j=i}^{2n} t[j] - j)\]
(\ (t[j] \) indicates the time when the \ (j \) position appears. I n fact, the upper bound of \ (\ max \) should be \ (i + n - 1 \), but obviously the later parts will not be better.)
Among them \ (n-1 \) and \ (t[j] - j \) can be calculated directly, which can be maintained by line tree.
For each interval maintenance \ (mx[i] \) represents the maximum value of the interval, \ (ans[i] \) represents the \ (min(i + \max\text {suffix}) \) of the left interval under the influence of the right interval
When merging, the influence of right interval on left interval is considered.
If \ (MX [RS] < MX [LS] \), we can directly update the answer with \ (ans[ls] \), and then recurse \ (ls(rs) \)
Otherwise, update the answer with mid and recurse \ (ls(ls) \)
In this way, half of the interval can be eliminated each time, so the complexity is \ (O(nlog^2n) \)
At the end of the query, the maximum value of \ ([n + 1, 2n] \) can be directly divided into two parts. In fact, the value of this part is \ (max[1, n] - n \)
Then you only need to maintain the segment tree of \ ([1, n] \)
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e6 + 10, INF = 1e9 + 7; template<typename A, typename B> inline bool chmin(A &x, B y) { if(x > y) {x = y; return 1;} else return 0; } template<typename A, typename B> inline bool chmax(A &x, B y) { if(x < y) {x = y; return 1;} return 0; } inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M, P, t[MAXN], q[MAXN]; int ans[MAXN], mx[MAXN]; #define ls k << 1 #define rs k << 1 | 1 int Query(int k, int l, int r, int val) { if(l == r) return l + max(mx[k], val); int mid = l + r >> 1; if(val < mx[rs]) return min(ans[k], Query(rs, mid + 1, r, val)); else return min(mid + val + 1, Query(ls, l, mid, val)); } void update(int k, int l, int r) { mx[k] = max(mx[ls], mx[rs]); ans[k] = Query(ls, l, (l + r) >> 1, mx[rs]); } void Modify(int k, int l, int r, int p, int v) { if(l == r) {mx[k] = v; return ;} int mid = l + r >> 1; if(p <= mid) Modify(ls, l, mid, p, v); else Modify(rs, mid + 1, r, p, v); update(k, l, r); } void Build(int k, int l, int r) { if(l == r) {mx[k] = t[l]; return ;} int mid = l + r >> 1; Build(ls, l, mid); Build(rs, mid + 1, r); update(k, l, r); } int main() { N = read(); M = read(); P = read(); for(int i = 1; i <= N; i++) t[i] = read(); for(int i = 1; i <= N; i++) t[i] -= i; Build(1, 1, N); int las = 0; printf("%d\n", las = (Query(1, 1, N, mx[1] - N) + N - 1)); while(M--) { int x = read(), y = read(); if(P) x ^= las, y ^= las; Modify(1, 1, N, x, y - x); printf("%d\n", las = (Query(1, 1, N, mx[1] - N) + N - 1)); } return 0; } /* 5 0 0 1 2 5 4 0 */