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.

- 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

http://blog.csdn.net/acm_cxlove/article/details/8565309

http://www.cnblogs.com/Rlemon/archive/2013/05/24/3096264.html

http://seter.is-programmer.com/posts/31907.html

http://blog.csdn.net/metalseed/article/details/8045038

  1 /* ***********************************************
2 Author        :kuangbin
3 Created Time  :2013-9-8 8:53:54
4 File Name     :F:\2013ACM练习\专题学习\主席树\ZOJ2112.cpp
5 ************************************************ */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <iostream>
10 #include <algorithm>
11 #include <vector>
12 #include <queue>
13 #include <set>
14 #include <map>
15 #include <string>
16 #include <math.h>
17 #include <stdlib.h>
18 #include <time.h>
19 using namespace std;
20
21 const int MAXN = 60010;
22 const int M = 2500010;
23 int n,q,m,tot;
24 int a[MAXN], t[MAXN];
25 int T[MAXN], lson[M], rson[M],c[M];
26 int S[MAXN];
27
28 struct Query
29 {
30     int kind;
31     int l,r,k;
32 }query[10010];
33
34 void Init_hash(int k)
35 {
36     sort(t,t+k);
37     m = unique(t,t+k) - t;
38 }
39 int hash(int x)
40 {
41     return lower_bound(t,t+m,x)-t;
42 }
43 int build(int l,int r)
44 {
45     int root = tot++;
46     c[root] = 0;
47     if(l != r)
48     {
49         int mid = (l+r)/2;
50         lson[root] = build(l,mid);
51         rson[root] = build(mid+1,r);
52     }
53     return root;
54 }
55
56 int Insert(int root,int pos,int val)
57 {
58     int newroot = tot++, tmp = newroot;
59     int l = 0, r = m-1;
60     c[newroot] = c[root] + val;
61     while(l < r)
62     {
63         int mid = (l+r)>>1;
64         if(pos <= mid)
65         {
66             lson[newroot] = tot++; rson[newroot] = rson[root];
67             newroot = lson[newroot]; root = lson[root];
68             r = mid;
69         }
70         else
71         {
72             rson[newroot] = tot++; lson[newroot] = lson[root];
73             newroot = rson[newroot]; root = rson[root];
74             l = mid+1;
75         }
76         c[newroot] = c[root] + val;
77     }
78     return tmp;
79 }
80
81 int lowbit(int x)
82 {
83     return x&(-x);
84 }
85 int use[MAXN];
86 void add(int x,int pos,int val)
87 {
88     while(x <= n)
89     {
90         S[x] = Insert(S[x],pos,val);
91         x += lowbit(x);
92     }
93 }
94 int sum(int x)
95 {
96     int ret = 0;
97     while(x > 0)
98     {
99         ret += c[lson[use[x]]];
100         x -= lowbit(x);
101     }
102     return ret;
103 }
104 int Query(int left,int right,int k)
105 {
106     int left_root = T[left-1];
107     int right_root = T[right];
108     int l = 0, r = m-1;
109     for(int i = left-1;i;i -= lowbit(i)) use[i] = S[i];
110     for(int i = right;i ;i -= lowbit(i)) use[i] = S[i];
111     while(l < r)
112     {
113         int mid = (l+r)/2;
114         int tmp = sum(right) - sum(left-1) + c[lson[right_root]] - c[lson[left_root]];
115         if(tmp >= k)
116         {
117             r = mid;
118             for(int i = left-1; i ;i -= lowbit(i))
119                 use[i] = lson[use[i]];
120             for(int i = right; i; i -= lowbit(i))
121                 use[i] = lson[use[i]];
122             left_root = lson[left_root];
123             right_root = lson[right_root];
124         }
125         else
126         {
127             l = mid+1;
128             k -= tmp;
129             for(int i = left-1; i;i -= lowbit(i))
130                 use[i] = rson[use[i]];
131             for(int i = right;i ;i -= lowbit(i))
132                 use[i] = rson[use[i]];
133             left_root = rson[left_root];
134             right_root = rson[right_root];
135         }
136     }
137     return l;
138 }
139 void Modify(int x,int p,int d)
140 {
141     while(x <= n)
142     {
143         S[x] = Insert(S[x],p,d);
144         x += lowbit(x);
145     }
146 }
147
148 int main()
149 {
150     //freopen("in.txt","r",stdin);
151     //freopen("out.txt","w",stdout);
152     int Tcase;
153     scanf("%d",&Tcase);
154     while(Tcase--)
155     {
156         scanf("%d%d",&n,&q);
157         tot = 0;
158         m = 0;
159         for(int i = 1;i <= n;i++)
160         {
161             scanf("%d",&a[i]);
162             t[m++] = a[i];
163         }
164         char op[10];
165         for(int i = 0;i < q;i++)
166         {
167             scanf("%s",op);
168             if(op[0] == 'Q')
169             {
170                 query[i].kind = 0;
171                 scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].k);
172             }
173             else
174             {
175                 query[i].kind = 1;
176                 scanf("%d%d",&query[i].l,&query[i].r);
177                 t[m++] = query[i].r;
178             }
179         }
180         Init_hash(m);
181         T[0] = build(0,m-1);
182         for(int i = 1;i <= n;i++)
183             T[i] = Insert(T[i-1],hash(a[i]),1);
184         for(int i = 1;i <= n;i++)
185             S[i] = T[0];
186         for(int i = 0;i < q;i++)
187         {
188             if(query[i].kind == 0)
189                 printf("%d\n",t[Query(query[i].l,query[i].r,query[i].k)]);
190             else
191             {
192                 Modify(query[i].l,hash(a[query[i].l]),-1);
193                 Modify(query[i].l,hash(query[i].r),1);
194                 a[query[i].l] = query[i].r;
195             }
196         }
197     }
198     return 0;
199 }

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客