$ >codeforces \space 650 D.? zip-line<$
Main Topic :
There is a length of \ (n\ ) of the sequence \ ( h\) ,\ (m\) the query, each request if the sequence of the second (x\) element into \ (y\) after the \ ( lis\) length
\ (1 \leq N, M \leq 4 \times 10^5\)
Problem Solving Ideas:
The form of the thought of the answer consists of two parts, part of \ ( lis\) containing \ ( x\ ), and part of \ ( lis\) that does not contain \ (x\)
The former obviously can maintain the left and right two \ (dp\) values and then the Chairman tree a few points, the difficulty lies in the latter.
For the second part, if \ (x\) is a common point before all \ (lis\) , then the answer to the second part is \ (lis-1\) , otherwise \ (lis\)
Consider how to determine whether a point is all (lis\) Common, the following first gives the method:
Statistics the position of each point in \ (lis\) , set \ (l[i]\) indicates the length of \ ( lis\) ending with \ (i\) from left to right,\ (r[i]\) represents the length of \ ( lis\) ending with \ ( i\ ) from right to left, if \ (l[i]+r[i]-1=lis\), then \ (i\) in \ (lis\) where the occurrence is \ (l[i]\), recorded as \ (pos[i]\)
If the point \ (x\) appears in \ (lis\) where \ (z\) only \ (x\) satisfies \ (pos[x] =z\) , then obviously \ (x\) cannot be substituted, it is a common point of all \ (lis\) . Otherwise there must be a scheme that does not go through \ (x\) to another satisfying \ (pos[i] = z\) (i\) , because \ (x\) cannot exist in two locations under any scheme, In this way, the length of the (lis\) will be longer and contradictory.
So we just need to count each of the \ (i\) is not in all the \ (lis\) appear, the total complexity of ( O ((n+m) logn) \)
A certain fairy said that the direct upper division (O (nlog^2n) \) was over
/*program by mangoyang*/#pragma gcc optimize ("ofast", "inline", "-ffast-math") #pragma gcc target ("Avx,sse2,sse3,sse4, MMX ") #include <bits/stdc++.h> #define INF (0x7f7f7f7f) #define MAX (A, B) ((a) > (b)? (a): (b) #define Min (A, B) ((a) < (b)? (a): (b) typedef long long ll;using namespace std;template <class t>inline void Read (T &x) {int f = 0, ch = 0; x = 0; for (;!isdigit (ch); ch = getchar ()) if (ch = = '-') f = 1; for (; isdigit (ch); ch = getchar ()) x = x * + ch-48; if (f) x =-X;} const int N = 400005;int H[n], l[n], r[n], g[n], pos[n], tot[n], Lis, N, M; struct segmenttree{int s[n*25], lc[n*25], rc[n*25], rt[n], size; Inline Segmenttree () {memset (S, 127, sizeof (s));} inline void ins (int &u, int pr, int l, int r, int pos, int x) {u = ++size, lc[u] = LC[PR], rc[u] = RC[PR]; if (L = = r) return (void) (S[u] = min (S[u], x)); int mid = L + R >> 1; if (POS <= mid) Ins (Lc[u], LC[PR], L, Mid, POS, x); ElsE ins (Rc[u], RC[PR], mid + 1, R, POS, x); S[u] = min (S[lc[u]], S[rc[u]]); } inline int query (int u, int l, int r, int x) {if (L = = r) return l; int mid = L + R >> 1; if (S[rc[u]] < x) return query (Rc[u], mid + 1, r, X); if (S[lc[u]] < x) return query (Lc[u], L, Mid, X); return 0; }}S1, S2;int Main () {read (n), read (m); for (int i = 1; I <= n; i++) read (H[i]); for (int i = 1; I <= n; i++) g[i] = inf; for (int i = 1; I <= n; i++) {L[i] = Lower_bound (g, G + N, H[i])-G; G[l[i]] = min (G[l[i]], h[i]), lis = Max (lis, l[i]); } for (int i = 0; I <= N; i++) g[i] = 0; G[0] =-inf; for (int i = n; I >= 1; i--) {R[i] = Lower_bound (g, G + N,-h[i])-G; G[r[i]] = min (G[r[i]],-h[i]); } for (int i = 1; I <= n; i++) if (L[i] + r[i]-1 = = lis) Pos[i] = L[i], tot[pos[i]]++; for (int i = 1; I <= n; i++) S1.ins (S1.rt[i], s1.rt[i-1], 1, N, L[i], h[i]); for (int i = n; I >= 1; i--) S2.ins (S2.rt[i], s2.rt[i+1], 1, N, R[i],-h[i]); for (int i = 1, x, y; i <= m; i++) {read (x), read (y); int res = 0; if (x > 1) Res + = S1.query (S1.rt[x-1], 1, n, y); if (x < n) Res + = S2.query (s2.rt[x+1], 1, N,-y); printf ("%d\n", Max (res + 1, (Pos[x] && (tot[pos[x]] = = 1))? Lis-1: Lis)); } return 0;}
Codeforces 650 D. zip-line