http://www.lydsy.com/JudgeOnline/problem.php?id=3065
Idea: Scapegoat Tree sets the weight segment tree.
When a scapegoat tree has a subtree larger than a certain Billy (scale), the violence is reconstructed, the time complexity of the subject: O (nlog^3n)
#include <algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<iostream>#include<vector>#defineAlpha 0.75#defineN 10000005intRead () {CharCh=getchar ();intt=0, f=1; while(ch<'0'|| Ch>'9'){if(ch=='-') f=-1; ch=GetChar ();} while('0'<=ch&&ch<='9') {t=t*Ten+ch-'0'; ch=GetChar ();} returnt*F;}inttmp;intN,m,sz,ans,root;intv[70005],dfn[70005],rt[70005],ls[70005],rs[70005];structseg{intL,r,sum;} A[n];std::vector<int>P,t,rec;intNewNode () {if(!rec.size ())return++sz; Else{ intk=Rec.back (); Rec.pop_back (); returnK; }}voidRecliam (int&x) { if(!x)return; Rec.push_back (x); Recliam (A[X].L); Recliam (A[X].R); A[x].sum=0; x=0;}voidInsertint&k,intLintRintValintf) { if(!k) k=NewNode (); if(L==R) {a[k].sum+=f;return;} intMid= (l+r) >>1; if(val<=mid) Insert (A[K].L,L,MID,VAL,F); ElseInsert (a[k].r,mid+1, r,val,f); A[k].sum=a[a[k].l].sum+a[a[k].r].sum; if(!a[k].sum) Recliam (k);}voidBuildint&k,intLintR) { intMid= (l+r) >>1; if(L>r)return; if(l==R) {k=dfn[l];insert (Rt[k],0,70000, V[k],1);return; } k=Dfn[mid]; Build (Ls[k],l,mid-1); Build (rs[k],mid+1, R); for(inti=l;i<=r;i++) Insert (Rt[k],0,70000, V[dfn[i]],1);}voidDelint&x) { if(!x)return; Recliam (Rt[x]); Del (ls[x]);p. push_back (x);d El (Rs[x]); X=0;}voidRebuildint&x) {del (x);ints1=p.size (); for(intI=1; i<=s1;i++) dfn[i]=p[i-1]; Build (x,1, S1); P.clear ();}intModifyintKintXintval) {Insert (Rt[k],0,70000, Val,1); intT,l=a[rt[ls[k]]].sum; if(L +1==x) {t=v[k];v[k]=Val;} Else if(l>=x) t=Modify (Ls[k],x,val); ElseT=modify (rs[k],x-l-1, Val); Insert (Rt[k],0,70000, t,-1); returnt;}voidQueryintKintLintR) { intL=a[rt[ls[k]]].sum,r=a[rt[k]].sum; if(l==1&&r==r) {t.push_back (rt[k]);return;} if(l<=l+1&&r>=l+1) P.push_back (V[k]); if(r<=L) query (LS[K],L,R); Else if(l>l+1) Query (rs[k],l-l-1, r-l-1); Else{ if(l<=L) query (ls[k],l,l); if(r>l+1) query (Rs[k],1, r-l-1); }}intSolve_query (intLintRintK) {query (ROOT,L,R); K--; intL=0, r=70000, S1=t.size (), s2=p.size (); while(l<R) { intMid= (l+r) >>1, sum=0; for(intI=0; i<s1;i++) sum+=a[a[t[i]].l].sum; for(intI=0; i<s2;i++) if(P[i]>=l&&p[i]<=mid) sum++; if(k<sum) { for(intI=0; i<s1;i++) t[i]=A[T[I]].L; R=mid; } Else{ for(intI=0; i<s1;i++) t[i]=A[T[I]].R; L=mid+1; k-=sum; }} t.clear ();p. Clear (); returnl;}voidInsertint&k,intXintval) { if(!k) {k=++N; Insert (Rt[k],0,70000, Val,1); V[K]=Val; return; } insert (Rt[k],0,70000, Val,1); intL=a[rt[ls[k]]].sum; if(l>=x) Insert (ls[k],x,val);ElseInsert (rs[k],x-l-1, Val); if(A[rt[k]].sum*alpha>std::max (Double) A[rt[ls[k]]].sum, (Double) (a[rt[rs[k]]].sum)) {if(TMP) {if(ls[k]==tmp) rebuild (ls[k]); Elserebuild (rs[k]); TMP=0; } }Elsetmp=K; }intMain () {n=read (); for(intI=1; i<=n;i++) v[i]=read (); for(intI=1; i<=n;i++) dfn[i]=i; Build (Root,1, N); M=read (); Charch[2];intx,y,k; while(m--) {scanf ("%s", CH); X=read (); Y=read (); x^=ans;y^=ans; Switch(ch[0]){ Case 'Q': K=read (); K^=ans;ans=solve_query (x,y,k);p rintf ("%d\n", ans); Break; Case 'M': Modify (Root,x,y); Break; Case 'I': tmp=0; Insert (root,x-1, y);if(TMP) {tmp=0; rebuild (root);} Break; } }}
Bzoj 3065 with insertion interval K small value