AC Channel: http://www.lydsy.com/JudgeOnline/problem.php?id=1901
Analysis
This is the title: without the modification of the interval K small reinforced version.
Let's look back at the solution to the previous question: Use a segment tree to make buckets and know the number of elements within a certain range of values. Use prefixes and know the number of elements within a certain subscript interval.
The combination of the two--building n Tree Segment tree, the first I segment tree represents the first I element in the numerical distribution. The prefix and the line tree can be used to know how many numbers are in a certain number range within the defined subscript interval, and then the binary finds the range of values where the K element is located.
Now if we press the idea above: still make buckets, still use prefixes and subtract. However, the modification of an element affects all the prefixes behind it, and the subsequent changes are also made. [But this seems like every operation is Nlogn ... Noticeably too slow]
So we think of a data structure that can quickly modify and get prefixes and--a tree-like array.
You only need to modify the elements of [J+lowbit (j)] and so on each modification, and the X, y two subtrees tree should be prefixed with each other and [J-lowbit (j)] and so on each time the two points go down.
The complexity of modifying and acquiring prefixes is logn, so each operation is (LOGN) ^2.
Then analyze the spatial complexity:
Before we look back, we built n trees but in fact many parts are the same, so we don't have any control over those parts, just make the node the same as the previous node, and then manipulate the changed parts.
So if we follow the above method is probably not very feasible, because now we each line of the tree represents the meaning of the tree array [for example, 6 means 5+6,12 means 9+10+11+12 and so on ...] That is, each modification of the previous one is likely to be different, the current node can not be set as the original node change [in fact, the original kind of modification is because the precursor only one and only modify a design, and we are not satisfied here], but a little thought is good, that is, I change every time there is only one chain, And each change is to add a chain up, not the entire line tree has been built to modify [somewhat similar to the construction of Trie Tree--from TB], so the complexity of the space is not tight, (n+m) (LOGN) is also acceptable.
The above is mainly about the use of what kind of line tree, the following specific how to use line tree problem.
Action 0: Because the line segment tree in here to do the bucket, so use hash to disperse, that is, preprocessing fast Platoon, and then find the time to find the corresponding position. [Note: Because there are actions to modify elements in the operation, Discretization needs to include these elements as well, which requires offline processing]
Action 1: Preprocessing the original sequence: for the first element, all nodes in the [I+lowbit (i) in the tree array after I and I are added to this element.
Action 2: Modify the value of an element at a location: first by the original value on this node and all subsequent nodes-1, and then press the new value on this node and all subsequent nodes +1
Action 3: Ask for the element in the section K in a range: similar to static. But each time you seek the prefix of the left and right subtree and use the stump array [because all the line-segment trees are the same meaning, the left son of all the nodes in the stump array is added up to the sum of the left son needed]. Then two points can be recursive.
On the code [there are traces of%h ...]
#include <cstdio>#include<cstring>#include<algorithm>Const intmaxn=200010;using namespacestd;intN,m,tot,top,sz;intV[MAXN],NUM[MAXN],HASH[MAXN];intA[MAXN],B[MAXN],K[MAXN],RT[MAXN];intl[ -],r[ -],a,b;Charord[2];BOOLFLAG[MAXN];structnode{intL,r,sz;} s[maxn* the];inlineintLowbit (intx) {returnx& (-x);}intFindintx) { intL=1, r=Tot,mid; while(l<=R) { intMid= (l+r) >>1; if(hash[mid]<x) l=mid+1; Elser=mid-1; } returnl;}voidUpdateintLastintLintRint&rt,intKeyintx) {RT=++sz,s[rt]=s[last];s[rt].sz+=x; if(L==R)return; intMid= (l+r) >>1; if(key<=mid) Update (S[LAST].L,L,MID,S[RT].L,KEY,X); ElseUpdate (s[last].r,mid+1, r,s[rt].r,key,x);}intQueryintLintRintk) { if(L==R)returnl; intI,suml=0, sumr=0; for(i=1; i<=a;i++) suml+=S[s[l[i]].l].sz; for(i=1; i<=b;i++) sumr+=S[s[r[i]].l].sz; intMid= (l+r) >>1; if(sumr-suml>=k) { for(i=1; i<=a;i++) l[i]=S[L[I]].L; for(i=1; i<=b;i++) r[i]=S[R[I]].L; returnquery (L,MID,K); } Else{ for(i=1; i<=a;i++) l[i]=S[L[I]].R; for(i=1; i<=b;i++) r[i]=S[R[I]].R; returnQuery (mid+1, r,k-(sumr-suml)); }}intMain () {#ifndef Online_judge freopen ("1901.in","R", stdin); Freopen ("1901.out","W", stdout);#endifscanf ("%d%d",&n,&m); for(intI=1; i<=n;i++) scanf ("%d", &v[i]), num[++top]=V[i]; for(intI=1; i<=m;i++) {scanf ("%s%d%d",ord,&a[i],&B[i]); if(ord[0]=='Q') scanf ("%d", &k[i]), flag[i]=true; Elsenum[++top]=C[i]; } sort (num+1, num+top+1); hash[++tot]=num[1]; for(intI=2; i<=top;i++) if(num[i]!=num[i-1]) hash[++tot]=Num[i]; for(intI=1; i<=n;i++){ intt=find (V[i]); for(intj=i;j<=n;j+=Lowbit (j)) Update (Rt[j],1, Tot,rt[j],t,1); } for(intI=1; i<=m;i++) if(Flag[i]) {a=b=0; a[i]--; for(intJ=a[i];j;j-=lowbit (j)) l[++a]=Rt[j]; for(intJ=b[i];j;j-=lowbit (j)) r[++b]=Rt[j]; printf ("%d\n", Hash[query (1, Tot,k[i])); } Else{ intt=find (V[a[i]); for(intj=a[i];j<=n;j+=Lowbit (j)) Update (Rt[j],1, tot,rt[j],t,-1); V[a[i]]=C[i]; T=find (B[i]); for(intj=a[i];j<=n;j+=Lowbit (j)) Update (Rt[j],1, Tot,rt[j],t,1); } return 0;}
View Code
BZOJ1901 Zju2112 Dynamic Rankings