The problem is equivalent to a tree-dependent backpack, allowing a chain to be free once per point.
The $f[i][j]$ means that the $i$ is considered in the Dfs order, and the volume is the maximum benefit of $j$.
First put the items that can not be free, and so on after the son and then put into the required items, then $i$ to the root of all points on the path is not free parts.
The DFS sequence is then flipped, and the $h[i][j]$ represents the maximum benefit of $j$ in terms of the DFS order taking into account the $i$ volume.
After traversing the son and then put the required items and not free items, then $i$ to the root path of all points are not counted.
So, for each leaf $i$, update the answer with $f[i][j]+h[i][k-j]$.
For items that are not free, you need to optimize the transfer with a monotone queue.
Time complexity $o (NK) $.
#include <cstdio> #include <cstring>const int n=20010,m=25520010;int case,n,m,k,t,i,fa[n],a[n],b[n],g[n] , nxt[n],ans,f[m],h[m];inline void Add (int x,int y) {nxt[y]=g[x];g[x]=y;} inline void up (Int&a,int b) {a<b? ( A=B): 0;} inline void Solve (Int*f,int a,int B) {int i,j=0,h=1,t=0; static int q[500010],p[500010]; for (i=0;i<=m;i++,j+=b) {f[i]-=j; while (H<=t&&f[q[t]]<f[i]) t--; Q[++t]=i; while (I-q[h]>a) h++; P[i]=f[q[h]]+j; } memcpy (f,p,t);} void dfsl (int x) {int i,j,a=a[x],b=b[x]; if (A) solve (f+x*k,a,b); for (I=g[x];i;i=nxt[i]) {memcpy (f+i*k,f+x*k,t); DFSL (i); B=b[i]; Int*s=f+x*k+1,*e=f+i*k; for (j=1;j<=m;j++,s++,e++) up (*s,*e+b); }}void DFSR (int x,int y) {int i,j,a=a[x],b=b[x]; Y+=b; for (I=g[x];i;i=nxt[i]) {memcpy (h+i*k,h+x*k,t); DFSR (I,y); B=b[i]; Int*s=h+x*k+1,*e=h+i*k; for (j=1;j<=m;j++,s++,e++) up (*s,*e+b); } if (!g[x]) {int*s=h+x*k+m,*e=f+x*k; For (j=0;j<=m;j++,s--, e++) up (ans,*s+*e+y); } if (A) solve (h+x*k,a,b[x]);} int main () {scanf ("%d", &case); while (case--) {scanf ("%d%d", &n,&m); k=m+1; t=k*sizeof (int); for (i=1;i<=n;i++) g[i]=0; for (i=1;i<=n;i++) {scanf ("%d%d%d", &fa[i],&a[i],&b[i]); a[i]--; if (Fa[i]) Add (fa[i],i); } memset (F+k,0,t); memset (h+k,0,t); DFSL (1); for (i=1;i<=n;i++) g[i]=0; for (i=n;i;i--) if (Fa[i]) Add (fa[i],i); ans=0; DFSR (1,0); printf ("%d\n", ans); } return 0;}
BZOJ4910: [Sdoi2017] apple tree