ZOJ 2112 Dynamic Rankings (动态第k大,树状数组套主席树)

Dynamic Rankings

Time Limit: 10 Seconds      Memory Limit: 32768 KB

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 }
原文地址:https://www.cnblogs.com/qldabiaoge/p/9119102.html