Title Link: http://www.lydsy.com/JudgeOnline/problem.php?id=2809
We consider each node as the manager of the best answer, it must be a priority to choose the less paid ninja. So first the whole subtrees tree Ninja are selected, if the sum is greater than $m$, then constantly delete the largest salary of the ninja.
Then consider merging nodes from bottom to top, we need a data structure that supports merging, and we think of a heuristic to combine a balanced tree or a heap.
The basic principle of the stack is to maintain a $dis$, which indicates the shortest distance from the root node to the leaf node and requires $dis[lch]>=dis[rch]$.
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5typedefLong Longll;6 intinline Readint () {7 intNum;Charch;8 while((Ch=getchar ()) <'0'|| Ch>'9'); num=ch-'0';9 while((Ch=getchar ()) >='0'&&ch<='9') num=num*Ten+ch-'0';Ten returnNum; One } A intn,m; - intc[100010],l[100010]; - intto[100010],ne[100010],fir[100010],cnt=0; the voidADD (intAintb) { -to[++cnt]=b; -ne[cnt]=Fir[a]; -fir[a]=CNT; + } - intlch[100010],rch[100010]; +ll sum[100010]; A intsiz[100010],dis[100010]; atll ans=0; - intMergeintXinty) { - if(!x| |! YreturnX?x:y; - if(c[x]<C[y]) swap (x, y); -rch[x]=merge (rch[x],y); - if(dis[lch[x]]<dis[rch[x]) swap (lch[x],rch[x]); indis[x]=dis[rch[x]]+1; -sum[x]=sum[lch[x]]+sum[rch[x]]+C[x]; tosiz[x]=siz[lch[x]]+siz[rch[x]]+1; + returnx; - } the intBuild (intx) { * intrt=x; $sum[rt]=C[x];Panax Notoginsengsiz[rt]=1; - for(inti=fir[x];i!=-1; i=Ne[i]) thert=Merge (Rt,build (to[i)); + while(sum[rt]>M) Art=merge (Lch[rt],rch[rt]); theAns=max (ans, (LL) siz[rt]*l[x]); + returnRT; - } $ intMain () { $memset (fir,-1,sizeof(FIR)); -n=readint (); -m=readint (); the for(intI=1; i<=n;i++){ - intFa=readint ();Wuyic[i]=readint (); thel[i]=readint (); - Add (fa,i); Wu } -Build (1); Aboutprintf"%lld\n", ans); $ return 0; -}
[BZOJ2809] [Apio2012]dispatching greedy + can and heap