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
Online Contest of Christopher‘s Adventure
解题:整体二分真是叼
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\n",ans[i]); 88 } 89 return 0; 90 }