[BZOJ1901] Zju2112 Dynamic Rankings
Question Description
Given a sequence of n A[1],a[2],a[3]......a[n], the program must answer this question: For a given i,j,k, the small number of K in A[i],a[i+1],a[i+2]......a[j] is (1≤k≤j-i+1), and, You can change the value of some a[i], and after the change, the program can continue to answer the above question for the changed a. You need to make a program that reads the sequence a from the input file and then reads in a series of instructions, including the Ask and modify instructions. For each inquiry instruction, you must output the correct answer. The first line has two positive integers n (1≤n≤10000), M (1≤m≤10000). Indicates the length of the sequence and the number of instructions, respectively. The second line has n number, which means a[1],a[2]......a[n], these numbers are smaller than 10^9. The next M-line describes each instruction, and the format of each line is one of the following two formats. Q I j K or C i t Q i j K (I,j,k is a number, 1≤i≤j≤n, 1≤k≤j-i+1) indicates an inquiry instruction asking for a small number of k in the A[i],a[i+1]......a[j]. C i T (1≤i≤n,0≤t≤10^9) means to change a[i] into T.
Input
Output
For each query, you need to output his answer, with each output occupying a separate line.
Input example
5 3 3 2 1 4 7 1432625 3
Output example
3 6
Data size and conventions
See " Question description "
Exercises
Hit a wave of line segment tree set Treap, compared to the Chairman tree set tree-like array is much slower ...
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype > #include <algorithm>using namespace Std;int read () {int x = 0, f = 1; char c = GetChar (); while (!isdigit (c)) {if ( c = = '-') f =-1; c = GetChar (); }while (IsDigit (c)) {x = x * + C-' 0 '; c = GetChar ();} return x * f;} #define MAXN 10005#define Maxnode 1280010struct Node {int V, r, Siz; Node () {}node (int _, int __): V (_), R (__) {}} ns[maxnode];int ToT, rt[maxn<<2], Fa[maxnode], ch[2][maxnode];void mai Ntain (int o) {ns[o].siz = 1;for (int i = 0; i < 2; i++) if (Ch[i][o]) Ns[o].siz + = Ns[ch[i][o]].siz;return;} void rotate (int u) {int y = Fa[u], z = fa[y], l = 0, r = 1;if (z) ch[ch[1][z]==y][z] = u;if (ch[1][y] = = u) Swap (L, R); Fa[u] = Z; Fa[y] = u; Fa[ch[r][u]] = y;ch[l][y] = Ch[r][u]; Ch[r][u] = Y;maintain (y); Maintain (U); return;} void Insert (int& o, int v) {if (!o) {ns[o = ++tot] = Node (V, rand ()); return maintain (o);} bool D = v > Ns[o].v;insert (ch[d][o], V); Fa[ch[d][o]] = o;if (Ns[ch[d][o]].r > NS[O].R) {int t = ch[d][o];rotate (t); o = t;} return maintain (o);} void del (int& o, int v) {if (!o) return, if (ns[o].v = = v) {if (!ch[0][o] &&!ch[1][o]) o = 0;else if (!ch[0][o]) {int t = Ch[1][o]; Fa[t] = Fa[o]; o = t;} else if (!ch[1][o]) {int t = Ch[0][o]; Fa[t] = Fa[o]; o = t;} else {bool d = NS[CH[1][O]].R > Ns[ch[0][o]].r;int t = ch[d][o]; rotate (t); o = T;del (Ch[d^1][o], v);}} else {bool d = v > Ns[o].v;del (ch[d][o], v);} return maintain (o);} int Find (int o, int v) {if (!o) return 0;int ls = ch[0][o]? ns[ch[0][o]].siz:0;if (v >= ns[o].v) return ls + 1 + Find ( Ch[1][o], v); return Find (Ch[0][o], v);} int N, val[maxn];void build (int L, int R, int o, int p) {insert (Rt[o], val[p]), if (L = = R) return; int M = L + R >> 1 , LC = O << 1, rc = LC | 1;if (P <= M) build (L, M, LC, p); else build (M+1, R, RC, p); return;} void Update (int L, int R, int o, int p, int v) {del (Rt[o], val[p]), insert (Rt[o], V), if (L = = R) return; int M =L + R >> 1, LC = O << 1, rc = LC | 1;if (P <= M) update (L, M, LC, P, v); Else update (m+1, R, RC, p, v); return; int QL, qr;int query (int L, int R, int o, int v) {if (QL <= L && R <= qr) return Find (Rt[o], v); int M = L + R >> 1, LC = O << 1, rc = LC | 1, ans = 0;if (ql <= m) ans + = query (L, M, LC, V); if (qr > m) ans + = query (m+1, R, RC, v); return ans; int main () {n = read (), int q = Read (), for (int i = 1; I <= n; i++) Val[i] = read (), build (1, N, 1, I), and while (q--) {Char TP[2]; scanf ("%s", TP), if (tp[0] = = ' Q ') {QL = read (); QR = read (); int k = read (); int l = 0, r = (int) 1e9; bool has = 0;while (L & Lt R) {int mid = L + R >> 1;if (query (1, N, 1, mid) < K) {L = mid + 1;if (query (1, N, 1, L) >= k) {has = 1; printf ( "%d\n", L); Break }}else r = Mid;} if (!has) printf ("%d\n", L);} else {int p = read (), V = Read (), update (1, N, 1, p, v); val[p] = v;}} return 0;}
[BZOJ1901] Zju2112 Dynamic Rankings