The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They have developed a more powerful system such that for N numbers a[1], a[2], ..., a[N], you can ask it like: what is the k-th smallest number of a[i], a[i+1], ..., a[j]? (For some i<=j, 0<k<=j+1-i that you have given to it). More powerful, you can even change the value of some a[i], and continue to query, all the same.
Your task is to write a program for this computer, which
- Reads N numbers from the input (1 <= N <= 50,000)
- Processes M instructions of the input (1 <= M <= 10,000). These instructions include querying the k-th smallest number of a[i], a[i+1], ..., a[j] and change some a[i] to t.
Input
The first line of the input is a single number X (0 < X <= 4), the number of the test cases of the input. Then X blocks each represent a single test case.
The first line of each block contains two integers N and M, representing N numbers and M instruction. It is followed by N lines. The (i+1)-th line represents the number a[i]. Then M lines that is in the following format
Q i j k or
C i t
It represents to query the k-th number of a[i], a[i+1], ..., a[j] and change some a[i] to t, respectively. It is guaranteed that at any time of the operation. Any number a[i] is a non-negative integer that is less than 1,000,000,000.
There're NO breakline between two continuous test cases.
Output
For each querying operation, output one integer to represent the result. (i.e. the k-th smallest number of a[i], a[i+1],..., a[j])
There're NO breakline between two continuous test cases.
Sample Input
2
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
3
6
3
6
绝望的主席树
这个动态查询快把我弄废了
现在处于懵逼状态 ,对着大佬的板子敲的
头疼欲裂
难受啊
等改天对这个主席树的理解深入后再再写一下补充一下这个博客吧
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 6e4 + 10; 4 int a[maxn], h[maxn]; 5 int T[maxn], L[maxn << 5], R[maxn << 5], sum[maxn << 5]; 6 int s[maxn], n, m, tot; 7 struct node { 8 int l, r, k; 9 int flag; 10 } op[10010]; 11 int build(int l, int r) { 12 int rt = (++tot); 13 sum[rt] = 0; 14 if (l != r) { 15 int m = (l + r) >> 1; 16 L[rt] = build(l, m); 17 R[rt] = build(m + 1, r); 18 } 19 return rt; 20 } 21 int update(int pre, int l, int r, int x, int val) { 22 int rt = (++tot); 23 L[rt] = L[pre], R[rt] = R[pre], sum[rt] = sum[pre] + val; 24 if (l < r) { 25 int m = (l + r) >> 1; 26 if (x <= m) L[rt] = update(L[pre], l, m, x, val); 27 else R[rt] = update(R[pre], m + 1, r, x, val); 28 } 29 return rt; 30 } 31 int lowbit(int x) { 32 return x & (-x); 33 } 34 int used[maxn]; 35 void add(int x, int pos, int val) { 36 while(x <= n) { 37 s[x] = update(s[x], 1, m, pos, val); 38 x += lowbit(x); 39 } 40 } 41 int Sum(int x) { 42 int ret = 0; 43 while(x > 0) { 44 ret += sum[L[used[x]]]; 45 x -= lowbit(x); 46 } 47 return ret; 48 } 49 int query(int u, int v, int lr, int rr, int l, int r, int k) { 50 if (l >= r) return l; 51 int m = (l + r) >> 1; 52 int temp = Sum(v) - Sum(u) + sum[L[rr]] - sum[L[lr]]; 53 if (temp >= k ) { 54 for (int i = u ; i ; i -= lowbit(i)) used[i] = L[used[i]]; 55 for (int i = v ; i ; i -= lowbit(i)) used[i] = L[used[i]]; 56 return query(u, v, L[lr], L[rr], l, m, k); 57 } else { 58 for (int i = u ; i ; i -= lowbit(i)) used[i] = R[used[i]]; 59 for (int i = v ; i ; i -= lowbit(i)) used[i] = R[used[i]]; 60 return query(u, v, R[lr], R[rr], m + 1, r, k - temp); 61 } 62 } 63 void modify(int x, int p, int d) { 64 while(x <= n) { 65 s[x] = update(s[x], 1, m, p, d); 66 x += lowbit(x); 67 } 68 } 69 int main() { 70 int t; 71 scanf("%d", &t); 72 while(t--) { 73 int q; 74 scanf("%d%d", &n, &q); 75 tot = 0; 76 m = 0; 77 for(int i = 1; i <= n; i++) { 78 scanf("%d", &a[i]); 79 h[++m] = a[i]; 80 } 81 for(int i = 0; i < q; i++) { 82 char s[10]; 83 scanf("%s", s); 84 if(s[0] == 'Q') { 85 scanf("%d%d%d", &op[i].l, &op[i].r, &op[i].k); 86 op[i].flag = 1; 87 } else { 88 scanf("%d%d", &op[i].l, &op[i].r); 89 op[i].flag = 0; 90 h[++m] = op[i].r; 91 } 92 } 93 sort(h + 1, h + 1 + m); 94 int mm = unique(h + 1, h + 1 + m) - h - 1; 95 m = mm; 96 T[0] = build(1, m); 97 for(int i = 1; i <= n; i++) 98 T[i] = update(T[i - 1], 1, m, lower_bound(h + 1, h + 1 + m, a[i]) - h, 1); 99 for(int i = 1; i <= n; i++) 100 s[i] = T[0]; 101 for(int i = 0; i < q; i++) { 102 if(op[i].flag) { 103 for(int j = op[i].l - 1; j; j -= lowbit(j)) 104 used[j] = s[j]; 105 for(int j = op[i].r; j; j -= lowbit(j)) 106 used[j] = s[j]; 107 printf("%d ", h[query(op[i].l - 1, op[i].r, T[op[i].l - 1], T[op[i].r], 1, m, op[i].k)]); 108 } else { 109 modify(op[i].l, lower_bound(h + 1, h + 1 + m, a[op[i].l]) - h, -1); 110 modify(op[i].l, lower_bound(h + 1, h + 1 + m, op[i].r) - h, 1); 111 a[op[i].l] = op[i].r; 112 } 113 } 114 } 115 return 0; 116 }