Rokua Topic Portal
The YCB a detailed explanation of the problem. %ycb%, please click here.
Thinking analysis
There is no way to apply the static Chairman tree. Because the \ (n\) segment tree is entangled with each other, once changed a point, the entire chairman of the tree will be changed again ...
I'm really going to forget. There is a data structure that can support single-point modification, interval query, and more importantly, the constant excellent it is dedicated to efficient maintenance of the prefix and!! It is--
! Tree-like array!
Before the static chairman tree to save each segment tree \ ([1,i]\), not also a huge prefix? The tree array is then nested in the tree of line segments to form a chair tree that supports dynamic modification. The node for each tree array is the root node of a segment tree.
For a chestnut, maintain a sequence of length \ (5\) , and the tree-like array actually grows like this--
The tree-like array is used to maintain the prefix and the. The first is to modify (set the modified element position to\ (i\))。 from subscript to\ (i\)The tree array node starts and jumps back each time (+=lowbit (i)), all the segments that jump to the tree are changed, the original value corresponds to the interval-1, the new value corresponds to the interval +1. We have to change.\ (log\)Tree.
Then the query. First put\ (l-1\)And\ (r\)All Jump Forward (-=lowbit (i)), each time you jump to write down. Request the current\ (size\), write it down.\ (log\)Tree by\ (r\)Get the node left son of\ (size\)and (on behalf of\ ([1,r]\)Of\ (size\)) minus\ (log\)Tree by\ (l-1\)Get the node left son of\ (size\)and (on behalf of\ ([1,l-1]\)Of\ (size\)) is\ ([l,r]\)Of\ (size\)。 When the son jumps to his left/right.\ (log\)nodes to jump together.
In fact, there is a problem, at the beginning of this Konjac Konjac think, is\ (n\)The line tree has not been able to share the memory, the space complexity will not be\ (O (N^2\log N) \)It?
There's really no need to worry about ...
Only consider the modification operation, each time there is\ (log\)Tree segments are picked out and each segment tree is modified only\ (log\)nodes, so the program runs down a trip, with only\ (n\log^2n\)A node has been visited, we just need to open the point of dynamic just fine.
Paste the following code:
#include <cstdio>#include <cstring>#include <algorithm>using namespaceStd#define R Register intConst intn=10009, m=4000009;//m: Open Nlog2 spaceBOOLOp[n];intl,p,n,a[n],b[n],c[n],d[n],g[n<<1];intRT[N],LC[M],RC[M],S[M];intpl,pr,reql[ -],reqr[ -];#define G Ch=getchar ()#define GO g;while (ch< '-') G#define IN (z) go;z=ch&15; G;while (ch> '-') z*=10,z+=ch&15,ginline voidUpdate (R P,r v)//Modify{R K=lower_bound (g+1, G+l+1, A[p])-G;//Find the corresponding value of discretization first for(R i=p;i<=n;i+=i&-i) {r*t=&rt[i],l=1, R=l,m; while(L!=R) {if(!*t) *t=++p;//Dynamic allocation of spaceS[*t]+=v; M= (l+r) >>1;if(k<=m) r=m,t=&lc[*t];ElseL=m+1,t=&rc[*t]; }if(!*t) *t=++p; S[*t]+=v; }}inline intAsk (R l,r r,r k) {R i,m,sum; Pl=pr=0; for(i=l-1; i;i-=i&-i) Reql[++pl]=rt[i]; for(i=r;i;i-=i&-i) reqr[++pr]=rt[i];//Log segment tree to be queried all written downL=1; r=l; while(L!=R) {m= (l+r) >>1; sum=0; for(i=1; i<=pr;++i) Sum+=s[lc[reqr[i]]; for(i=1; i<=pl;++i) Sum-=s[lc[reql[i]];//Add together minus if(k<=sum) { for(i=1; i<=pl;++i) Reql[i]=lc[reql[i]]; for(i=1; i<=pr;++i) Reqr[i]=lc[reqr[i]]; R=m; }//together to the same side of the son jump Else{ for(i=1; i<=pl;++i) Reql[i]=rc[reql[i]]; for(i=1; i<=pr;++i) Reqr[i]=rc[reqr[i]]; L=m+1; k-=sum; } }returnG[L];}intMain () {Register CharCh R M,i; In (n); in (m); L=n; for(i=1; i<=n;++i) {in (A[i]);} memcpy (G,a, (n+1) <<2); for(i=1; i<=m;++i) {go;op[i]=ch==' Q '; In (B[i]); in (C[i]);if(Op[i]) {in (D[i]);}ElseG[++l]=c[i];//becomes dynamic, the values that need to be modified after discretization are also taken into account, so save all operations first} Sort (g+1, G+l+1); L=unique (g+1, G+l+1)-G-1;//Discretization for(i=1; i<=n;++i) Update (I,1);//At the beginning or every point to be updated again for(i=1; i<=m;++i) {if(Op[i]) printf ("%d\n", ask (B[i],c[i],d[i]));Else{Update (B[i],-1);//Note that the previous value to be replaced is to be lostA[b[i]]=c[i]; Update (B[i],1); } }return 0;}
Dynamic Ranking (Chairman tree, tree set tree, tree-like array)