Dynamic Rankings Time limit: Seconds Memory Limit: 32768 KB
The company Dynamic rankings have developed a new kind of computer that's no longer satisfied with the query like to SI Mply Find the k-th smallest number of the given N numbers. They has developed a more powerful system such this 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, and 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 &L t;= 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 was 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 the 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 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, at any time of the operation. Any number a[i] is a non-negative an integer that's less than 1,000,000,000.
There ' re NO breakline between, continuous test cases.
Output
For each querying operation, an 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, continuous test cases.
Sample Input
25 33 2 1 4 7Q1 4 3C2 6Q2 5 35 33 2 1 4 7Q1 4 3C2 6Q2 5 3
Sample Output
3 6 3 6
Solution
It's a classic question of the whole dichotomy.
It's probably a modified interval K-small.
The offline approach is used here
First, when the data range is large, all the interval numbers that appear in the input are discretized
After that, save all the queries, treat the modifications as 2 operations, the assignment operation as 1, and the 3 operation to ask
The discretization of the digital interval to do two points
The general idea is this:
1. Determine the scope of the answer [l,r],mid=l+r>>1;
2. Calculate the contribution of the operation of the answer within [l,mid] to the operation of the answer within [mid+1,r];
3. Put the answer in [L,mid] in the queue q1,solve (Q1,l,mid)
Put the answer within [mid+1,r] into Q2,solve (q2,mid+1,r)
Since the inquiry and operation are processed in chronological order, in order to satisfy the dichotomy, we need to sort out the interval of inquiry and operation, here we use a tree-like array to maintain the number of n in the virtual interval of the problem, and use the contribution of query and operation in the statistical interval of the tree array. Interval modification with difference.
Each enquiry and operation is then divided into two intervals to be processed separately.
Log answers whenever the current interval has shrunk to a point
The final output can be as required
#include <map>#include<vector>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespacestd;Const intm=300000; inlineintRead () {intx=0, C=getchar (), f=1; for(;c< -|| C> $; c=GetChar ())if(! (c^ $)) F=-1; for(;c> -&&c< -; c=GetChar ()) x= (x<<1) + (x<<3) +c- -; returnx*F;} Vector<int>V;map<int,int>h;intQcnt,pcnt,a[m],ans[m],c[m],n,tmp[m];structque{intX,y,typ,cur,kth,pos;} Q[m],q1[m],q2[m];inlinevoidAddintXintd) { for(;x<=n;x+=x& (-x)) c[x]+=D;} InlineintSumintx) { intres=0; for(;x;x-=x& (-x) Res+=C[x]; returnRes;}voidDivideinthdintTlintLintR) { if(hd>TL)return; if(l==R) { for(inti=hd;i<=tl;i++) if(q[i].typ==3) Ans[q[i].pos]=l; return; } intMid=l+r>>1; for(inti=hd;i<=tl;i++){ if(q[i].typ==3) Tmp[i]=sum (Q[I].Y)-sum (q[i].x-1); Else if(q[i].typ==2&&q[i].y<=mid) Add (q[i].x,-1); Else if(q[i].typ==1&&q[i].y<=mid) Add (q[i].x,1); } for(inti=hd;i<=tl;i++){ if(q[i].typ==2&&q[i].y<=mid) Add (q[i].x,1); Else if(q[i].typ==1&&q[i].y<=mid) Add (q[i].x,-1); } intl1=0, l2=0; for(inti=hd;i<=tl;i++){ if(q[i].typ==3){ if(q[i].cur+tmp[i]>=q[i].kth) q1[++l1]=Q[i]; Else{q[i].cur+=Tmp[i]; q2[++l2]=Q[i]; } } Else{ if(q[i].y<=mid) q1[++l1]=Q[i]; Elseq2[++l2]=Q[i]; } } for(intI=1; i<=l1;i++) Q[hd+i-1]=Q1[i]; for(intI=1; i<=l2;i++) Q[hd+l1+i-1]=Q2[i]; Divide (Hd,hd+l1-1, L,mid); Divide (HD+l1,tl,mid+1, R);}intMain () {intm,t; T=read (); while(t--) {qcnt=pcnt=0; V.clear (); H.clear (); Memset (A,0,sizeof(a)); Memset (c,0,sizeof(c)); memset (TMP,0,sizeof(TMP)); N=read (), m=read (); for(intI=1; i<=n;i++) {A[i]=read (); q[++qcnt].x=i; Q[qcnt].y=A[i]; Q[qcnt].typ=1; V.push_back (A[i]); } for(intI=1; i<=m;i++){ Charsign[4]; intx, Y, Z scanf ("%s", sign); if(sign[0]=='Q') {x=read (), Y=read (), z=read (); q[++qcnt].x=x; Q[qcnt].y=y; Q[qcnt].kth=Z; Q[qcnt].typ=3; Q[qcnt].cur=0; Q[qcnt].pos=++pcnt; } Else{x=read (), y=read (); q[++qcnt].x=x; Q[qcnt].y=A[x]; Q[qcnt].typ=2; q[++qcnt].x=x; Q[qcnt].y=y; Q[qcnt].typ=1; A[X]=y; V.push_back (y); }} sort (V.begin (), V.end ()); V.erase (Unique (V.begin (), V.end ()), V.end ()); for(intI=0; I<v.size (); i++) H[v[i]]=i+1; for(intI=1; i<=qcnt;i++) if(q[i].typ<=2) Q[i].y=H[Q[I].Y]; Divide (1, qcnt,1, V.size ()); for(intI=1; i<=pcnt;i++) printf ("%d\n", v[ans[i]-1]); } return 0;}
[bzoj1901] [zoj2112] [Dynamic Rankings]