题解:
可并大根对维护即可
注意long long
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=200009; int n,m; int abl[maxn]; long long ans=0; int fa[maxn],ch[maxn][2],dis[maxn]; long long sum[maxn]; int siz[maxn],ky[maxn]; int Mer(int x,int y){ if((x==0)||(y==0))return x+y; if(ky[x]<ky[y])swap(x,y); ch[x][1]=Mer(ch[x][1],y); sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+ky[x]; siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; if(dis[ch[x][1]]>dis[ch[x][0]])swap(ch[x][0],ch[x][1]); dis[x]=dis[ch[x][1]]+1; return x; } int root; int cntedge=0; int head[maxn]={0}; int to[maxn<<1],nex[maxn<<1]; void Addedge(int x,int y){ nex[++cntedge]=head[x]; to[cntedge]=y; head[x]=cntedge; } int Dp(int x){ int rt=x; for(int i=head[x];i;i=nex[i]){ rt=Mer(rt,Dp(to[i])); } while(sum[rt]>m){ fa[ch[rt][0]]=0; fa[ch[rt][1]]=0; rt=Mer(ch[rt][0],ch[rt][1]); } ans=max(ans,1LL*abl[x]*siz[rt]); return rt; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i){ int x;scanf("%d",&x); if(x==0)root=i; else Addedge(x,i); scanf("%d%d",&ky[i],&abl[i]); siz[i]=1;sum[i]=ky[i]; } Dp(root); cout<<ans<<endl; return 0; }