Just learned the whole two points, follow the pace of God Ben to the problem ...
God Ben: This question is not a two-point answer naked question? I:......
Perhaps I am really too weak:
But at least it's a, tell me about my ideas:
First, we separate an answer, mid, and then sweep the query within the current interval, if the number of X>=mid added, then the value of the interval is added 1, so that the number of interval >=mid can be calculated.
Then, judging by these things, the current query should be left or right, and recursion will do. Also do not forget to ask is the interval k large, so for the left side of the inquiry to the first to calculate the contribution.
Paste the following code:
1#include <cstdio>2 #defineMAXN 500103 4 using namespacestd;5typedefLong LongLlg;6 7 structdata{8 intTp,l,r,k,id;9 }S[MAXN],ZL[MAXN],ZR[MAXN];Ten intN,m,ans[maxn],tt; One Llg C1[MAXN],C2[MAXN]; A - intGetint () { - intw=0, q=0; the CharC=GetChar (); - while((c<'0'|| C>'9') &&c!='-') c=GetChar (); - if(c=='-') q=1, c=GetChar (); - while(c>='0'&&c<='9') w=w*Ten+c-'0', c=GetChar (); + returnq?-w:w; - } + A voidAddintXintY) { for(inti=x;i<=n;i+=i& (-i)) c1[i]+=y,c2[i]+= (LLG) x*y;} atLLG sum (intx) { -Llg ans (0); - for(inti=x;i;i-=i& (-i)) ans+= (x+1) *c1[i]-C2[i]; - returnans; - } - in voidSolveintTopintEndintLintR) { - if(l==R) { to for(inti=top;i<=end;i++) +ans[s[i].id]=l; - return; the } * intmid=l+r+1>>1, Lo (0), RO (0); $ BOOLll0), RR (0); Llg x;Panax Notoginseng for(inti=top;i<=end;i++) - if(s[i].tp==1) the if(s[i].k>=mid) Add (S[I].L,1), Add (s[i].r+1,-1), zr[++ro]=S[i]; + Elsezl[++lo]=S[i]; A Else{ theX=sum (S[I].R)-sum (s[i].l-1); + if(X>=S[I].K) zr[++ro]=s[i],rr=1; - ElseS[i].k-=x,zl[++lo]=s[i],ll=1; $ } $ for(inti=top;i<=end;i++) - if(s[i].tp==1&& s[i].k>=mid) Add (s[i].l,-1), Add (s[i].r+1,1); - for(intI=1; i<=lo;i++) s[top+i-1]=Zl[i]; the for(intI=1; i<=ro;i++) s[top+i+lo-1]=Zr[i]; - if(ll) Solve (top,top+lo-1, l,mid-1);Wuyi if(RR) Solve (top+lo,end,mid,r); the } - Wu intMain () { -N=getint (); m=getint (); About for(intI=1; i<=m;i++){ $s[i].tp=getint (); -S[i].l=getint (); S[i].r=getint (); -s[i].k=getint (); - if(s[i].tp==2) s[i].id=++tt; A } +Solve1M1, n); the for(intI=1; i<=tt;i++) -printf"%d\n", Ans[i]); $ return 0; the}
Bzoj Zjoi2013 k Large number query