ZJU 2112 Dynamic Rankings

Dynamic Rankings

Time Limit: 10000ms
Memory Limit: 32768KB
This problem will be judged on ZJU. Original ID: 2112
64-bit integer IO format: %lld      Java class name: Main
 

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


(adviser)
Site: http://zhuzeyuan.hp.infoseek.co.jp/index.files/our_contest_20040619.htm

 

Source

 
解题:整体二分真是叼
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 300010;
 4 const int INF = 1000000000;
 5 struct QU {
 6     int x,y,k,id,d;
 7 } Q[maxn],A[maxn],B[maxn];
 8 int a[maxn],c[maxn],ans[maxn],tot;
 9 void add(int i,int val) {
10     while(i < maxn) {
11         c[i] += val;
12         i += i&-i;
13     }
14 }
15 int sum(int i,int ret = 0) {
16     while(i > 0) {
17         ret += c[i];
18         i -= i&-i;
19     }
20     return ret;
21 }
22 void solve(int lt,int rt,int L,int R) {
23     if(lt > rt) return;
24     if(L == R) {
25         for(int i = lt; i <= rt; ++i)
26             if(Q[i].id) ans[Q[i].id] = L;
27         return;
28     }
29     int mid = (L + R)>>1,a = 0,b = 0;
30     for(int i = lt; i <= rt; ++i) {
31         if(Q[i].id) {
32             int tmp = sum(Q[i].y) - sum(Q[i].x-1);
33             if(Q[i].d + tmp >= Q[i].k) A[a++] = Q[i];
34             else {
35                 Q[i].d += tmp;
36                 B[b++] = Q[i];
37             }
38         } else if(Q[i].y <= mid) {
39             add(Q[i].x,Q[i].d);
40             A[a++] = Q[i];
41         } else B[b++] = Q[i];
42     }
43     for(int i = lt; i <= rt; ++i)
44         if(!Q[i].id && Q[i].y <= mid) add(Q[i].x,-Q[i].d);
45     for(int i = 0; i < a; ++i) Q[lt + i] = A[i];
46     for(int i = 0; i < b; ++i) Q[lt + a + i] = B[i];
47     solve(lt,lt + a - 1,L,mid);
48     solve(lt + a,rt,mid + 1,R);
49 }
50 int main() {
51     int kase,n,m,cnt,x,y;
52     scanf("%d",&kase);
53     while(kase--) {
54         scanf("%d%d",&n,&m);
55         memset(c,0,sizeof c);
56         cnt = tot = 0;
57         for(int i = 1; i <= n; ++i) {
58             scanf("%d",a + i);
59             Q[++tot].y = a[i];
60             Q[tot].x = i;
61             Q[tot].id = 0;
62             Q[tot].d = 1;
63         }
64         char op[3];
65         for(int i = 1; i <= m; ++i) {
66             scanf("%s",op);
67             if(op[0] == 'Q') {
68                 tot++;
69                 scanf("%d%d%d",&Q[tot].x,&Q[tot].y,&Q[tot].k);
70                 Q[tot].id = ++cnt;
71                 Q[tot].d = 0;
72             } else {
73                 scanf("%d%d",&x,&y);
74                 Q[++tot].x = x;
75                 Q[tot].y = a[x];
76                 Q[tot].id = 0;
77                 Q[tot].d = -1;
78 
79                 Q[++tot].x = x;
80                 Q[tot].y = a[x] = y;
81                 Q[tot].id = 0;
82                 Q[tot].d = 1;
83             }
84         }
85         solve(1,tot,0,INF);
86         for(int i = 1; i <= cnt; ++i)
87             printf("%d
",ans[i]);
88     }
89     return 0;
90 }
View Code

再写一遍

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int INF = 0x3f3f3f3f;
 4 const int maxn = 100010;
 5 struct QU {
 6     int id,x,y,k,d;
 7     QU(int id = 0,int x = 0,int y = 0,int d = 0) {
 8         this->id = id;
 9         this->x = x;
10         this->y = y;
11         this->d = d;
12     }
13 } Q[maxn],A[maxn],B[maxn];
14 
15 int c[maxn],ans[maxn],d[maxn];
16 void add(int i,int val) {
17     while(i < maxn) {
18         c[i] += val;
19         i += i&-i;
20     }
21 }
22 int sum(int i,int ret = 0) {
23     while(i > 0) {
24         ret += c[i];
25         i -= i&-i;
26     }
27     return ret;
28 }
29 void solve(int lt,int rt,int L,int R) {
30     if(lt > rt) return;
31     if(L == R) {
32         for(int i = lt; i <= rt; ++i)
33             if(Q[i].id != -1) ans[Q[i].id] = L;
34         return;
35     }
36     int mid = (L + R)>>1,a = 0,b = 0;
37     for(int i = lt; i <= rt; ++i) {
38         if(Q[i].id > -1) {
39             int tmp = sum(Q[i].y) - sum(Q[i].x-1);
40             if(Q[i].d + tmp >= Q[i].k) A[a++] = Q[i];
41             else {
42                 Q[i].d += tmp;
43                 B[b++] = Q[i];
44             }
45         } else if(Q[i].y <= mid) {
46             add(Q[i].x,Q[i].d);
47             A[a++] = Q[i];
48         } else B[b++] = Q[i];
49     }
50     for(int i = lt; i <= rt; ++i)
51         if(Q[i].id == -1 && Q[i].y <= mid)
52             add(Q[i].x,-Q[i].d);
53     for(int i = 0; i < a; ++i)
54         Q[i+lt] = A[i];
55     for(int i = 0; i < b; ++i)
56         Q[i + lt + a] = B[i];
57     solve(lt,lt + a-1,L,mid);
58     solve(lt+a,rt,mid+1,R);
59 }
60 int main() {
61     int kase,n,m,tot,ask,x,y;
62     char cmd[10];
63     scanf("%d",&kase);
64     while(kase--) {
65         scanf("%d%d",&n,&m);
66         for(int i = tot = 0; i < n; ++i) {
67             scanf("%d",&d[i+1]);
68             Q[tot++] = QU(-1,i+1,d[i+1],1);
69         }
70         for(int i = ask = 0; i < m; ++i) {
71             scanf("%s",cmd);
72             if(cmd[0] == 'Q') {
73                 scanf("%d%d%d",&Q[tot].x,&Q[tot].y,&Q[tot].k);
74                 Q[tot].id = ask++;
75                 Q[tot++].d = 0;
76             } else {
77                 scanf("%d%d",&x,&y);
78                 Q[tot++] = QU(-1,x,d[x],-1);
79                 Q[tot++] = QU(-1,x,d[x] = y,1);
80             }
81         }
82         solve(0,tot-1,0,INF);
83         for(int i = 0; i < ask; ++i)
84             printf("%d
",ans[i]);
85     }
86     return 0;
87 }
View Code
原文地址:https://www.cnblogs.com/crackpotisback/p/4748594.html