The old number was written with a left-leaning tree.
And now with the Chairman tree, feel the understanding deepened a lot.
The first is that the DFS sequence manages the interval of each node, then violently enumerates each manager and then, in the interval, can find the maximum number of people to pay.
It is worth noting that the value of the current position should be the value of the sorted array instead of the value of the original current position, adjusted for one noon.
Chairman Tree:
#include <cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>using namespaceStd;typedefLong LongLL;intN; LL m; LL c[210000],ld[210000];structnode{intX,y,next;} a[210000];intlen,last[210000];voidInsintXinty) {Len++; a[len].x=x;a[len].y=y; A[len].next=last[x];last[x]=Len;}structchairtree{intLC,RC; LL C,sum;} tr[4100000];inttrlen,rt[210000];intMaketree (intNowintLintR,ll k,ll s) { if(now==0) now=++Trlen; TR[NOW].C+ +, tr[now].sum+=s; if(l<r) {intMid= (L+R)/2; if(K<=mid) tr[now].lc=Maketree (tr[now].lc,l,mid,k,s); ElseTr[now].rc=maketree (tr[now].rc,mid+1, r,k,s); } returnNow ;}intMergeintXinty) { if(x==0|| y==0)returnx+y; TR[X].C+=tr[y].c; Tr[x].sum+=tr[y].sum; TR[X].LC=merge (TR[X].LC,TR[Y].LC); Tr[x].rc=merge (tr[x].rc,tr[y].rc); returnx;} LL tt[210000]; LL c,p;BOOLBK;voidGetpeopleintXintYintLintR) { if(bk==false)return ; LL cc=tr[x].c-tr[y].c,sum=tr[x].sum-tr[y].sum; if(c+sum<=m) {C+=sum, p+=cc; if(c+tt[l]>m) bk=false; } Else if(l==r) {LL bi=min ((m-c)/tt[l],cc); C+=bi*tt[l], p+=bi; if(bi==0) bk=false; } Else { intMid= (L+R)/2; Getpeople (Tr[x].lc,tr[y].lc,l,mid); Getpeople (Tr[x].rc,tr[y].rc,mid+1, R); }}ll Erfen (LL k) {intL=1, r=N,ret; while(l<=r) {intMid= (L+R)/2; if(tt[mid]<=k) {ret=mid; L=mid+1; } Elser=mid-1; } returnret;}introot,z,l[210000],r[210000];voidDfsintx) {L[x]=++Z; RT[Z]=maketree (Rt[z],1, N,erfen (C[x]), c[x]); RT[Z]=merge (rt[z],rt[z-1]); for(intk=last[x];k;k=A[k].next) { inty=a[k].y; DFS (y); } R[x]=Z;}intMain () {intFA; scanf ("%d%lld",&n,&m); for(intI=1; i<=n;i++) {scanf ("%d%lld%lld", &fa,&c[i],&ld[i]); tt[i]=C[i]; if(fa==0) root=i; Elseins (fa,i); } sort (TT+1, tt+n+1); Z=0; trlen=0;d FS (root); LL Mmax=0; for(intI=1; i<=n;i++) {C=0; p=0; bk=true; Getpeople (Rt[r[i]],rt[l[i]-1],1, N); Mmax=max (mmax,ld[i]*P); } printf ("%lld\n", Mmax); return 0;}
Left-leaning tree:
#include <cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespaceStd;typedefLong LongLL;intn,m;structnode{intX,y,next;} a[1100000];intlen,last[1100000];structheap{intL,r; LL c,d; Heap () {L=r=d=0; }}h[1100000];introot[1100000];voidInsintXinty) {Len++; a[len].x=x;a[len].y=y; A[len].next=last[x];last[x]=Len;}intMarge (intXinty) { if(x==0|| y==0)returnx+y; if(H[X].C<H[Y].C) Swap (x, y);//maintenance of large piles by salary, kick heap first maintenance cost less than M convenientH[x].r=Marge (h[x].r,y); if(h[h[x].l].d<h[h[x].r].d) Swap (H[X].L,H[X].R); H[X].D=h[h[x].r].d+1; returnx;} LL p[1100000],s[1100000];//number of people, cost of moneyLL ans,ld[1100000];voidDfsintX//The DFS sequence allows each point to become a large heap, covering all situations{ for(intk=last[x];k;k=A[k].next) { inty=a[k].y; DFS (y); P[X]+=p[y];s[x]+=S[y]; ROOT[X]=Marge (Root[x],root[y]); } while(s[x]>m) {s[x]-=h[root[x]].c;p[x]--; ROOT[X]=Marge (H[ROOT[X]].L,H[ROOT[X]].R); } if(Ld[x]*p[x]>ans) ans=ld[x]*p[x];} intMain () {intB; scanf ("%d%d",&n,&m); for(intI=1; i<=n;i++) {scanf ("%d%lld%lld",&b,&h[i].c,&Ld[i]); Ins (b,i);p [i]=1; s[i]=h[i].c;root[i]=i; } ans=0;d FS (1); printf ("%lld\n", ans); return 0;}
bzoj2809: [apio2012]dispatching