以前不太知道可并堆还能自底向上建感觉思路还是非常好的
#include<cstdio>
#include<algorithm>using std::swap;
const int MAXn=100000+9;
int head[MAXn],next[MAXn],end[MAXn],ne;
inline void add(int a,int b)
{
end[++ne]=b;
next[ne]=head[a];
head[a]=ne;
}
int c[MAXn];
int d[MAXn],lc[MAXn],rc[MAXn],cnt[MAXn];
long long sum[MAXn];
int merge(int a,int b)
{
if(!a || !b)
return a|b;
if(c[a]<c[b])
swap(a,b);
rc[a]=merge(rc[a],b);
swap(lc[a],rc[a]);
d[a]=d[rc[a]]+1;
sum[a]=sum[lc[a]]+sum[rc[a]]+c[a];
cnt[a]=cnt[lc[a]]+cnt[rc[a]]+1;
return a;
}
int m;
long long ans,l[MAXn];
int work(int u)
{
int i,t=u;
sum[u]=c[u];
cnt[u]=1;
for(i=head[u];i;i=next[i])
t=merge(t,work(end[i]));
for(;sum[t]>m;)
t=merge(lc[t],rc[t]);
ans=std::max(cnt[t]*l[u],ans);
return t;
}
int main()
{
int n,i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i)
{ scanf("%d%d%lld",&j,c+i,l+i);
if(j)add(j,i);
}
d[0]=-1;
work(1);
printf("%lld\n",ans);
return 0;
}