今年APIO被启发式合并坑了有木有啊!!!!
于是回家就写启发式合并啊!!!!
WA了N次最后发现语句写反了,伤不起啊有木有!!!!
无非就是把原节点链表拆开然后插入有木有啊!!!!
于是我就直接贴代码了啊!!!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#define fa(x) tree[x].fa
#define data(x) tree[x].data
#define sum(x) tree[x].sum
#define son(x) tree[x].size
#define l(x) tree[x].l
#define r(x) tree[x].r
using namespace std;
struct node
{
int fa,data,size,l,r;
long long sum;
} tree[100001];
vector<int> graph[100001];
vector<int> seq;
int l[100001],c[100001],n,m,b,root[100001],ans[100001];
inline void update(int x)
{
if (x!=0)
son(x)=son(l(x))+son(r(x))+1,sum(x)=sum(l(x))+sum(r(x))+data(x);
}
inline void right_rotate(int x)
{
int y=fa(x),tmp=r(x);
if (l(fa(y))==y)
l(fa(y))=x;
else
r(fa(y))=x;
fa(x)=fa(y),fa(y)=x,l(y)=tmp,fa(tmp)=r(x)=y;
update(y),update(x);
}
inline void left_rotate(int x)
{
int y=fa(x),tmp=l(x);
if (l(fa(y))==y)
l(fa(y))=x;
else
r(fa(y))=x;
fa(x)=fa(y),fa(y)=x,r(y)=tmp,fa(tmp)=l(x)=y;
update(y),update(x);
}
inline void splay(int rr,int x,int pos)
{
int f=fa(rr);
while (fa(x)!=f)
{
int y=fa(x),z=fa(y);
if (z==f)
{
if (l(y)==x)
right_rotate(x);
else
left_rotate(x);
break;
}
if (l(z)==y)
{
if (l(y)==x)
right_rotate(y),right_rotate(x);
else
left_rotate(x),right_rotate(x);
}
else
{
if (l(y)==x)
right_rotate(x),left_rotate(x);
else
left_rotate(y),left_rotate(x);
}
}
if (rr==root[pos])
root[pos]=x;
}
inline void insert(int pos,int x)
{
l(x)=r(x)=fa(x)=0;
int val=data(x);
if (pos==0)
{
son(x)=1,sum(x)=data(x),root[pos]=x;
return;
}
int k=root[pos];
while (1)
{
if (val<data(k))
{
if (l(k)==0)
break;
k=l(k);
}
else
{
if (r(k)==0)
break;
k=r(k);
}
}
son(k)++,fa(x)=k,sum(k)+=data(x),sum(x)=data(x),son(x)=1;
if (val<data(k))
l(k)=x;
else
r(k)=x;
splay(root[pos],x,pos);
}
void search(int x)
{
if (x==0)
return;
seq.push_back(x);
search(l(x)),search(r(x));
}
inline void comb(int t,int s)
{
seq.clear();
search(root[s]);
for (int i=0;i<seq.size();i++)
insert(t,seq[i]);
}
inline int get_ans(int r)
{
int x=root[r],ans=0,temp=m;
while (x!=0 && temp>0)
{
if (sum(x)-sum(r(x))>temp)
x=l(x);
else
temp-=(sum(x)-sum(r(x))),ans+=(son(l(x))+1),x=r(x);
}
return ans;
}
void dfs(int r)
{
int temp=0,k=0;
for (int i=0;i<graph[r].size();i++)
{
dfs(graph[r][i]);
if (temp<son(root[graph[r][i]]))
k=root[graph[r][i]],temp=son(root[graph[r][i]]);
}
for (int i=0;i<graph[r].size();i++)
{
int j=graph[r][i];
if (j==k)
continue;
comb(k,j);
}
insert(k,r),root[r]=r;
ans[r]=get_ans(r);
}
int main()
{
freopen("dispatching.in","r",stdin);
freopen("dispatching.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%d%d%d",&b,c+i,l+i);
graph[b].push_back(i),data(i)=c[i];
}
dfs(1);
long long temp=0,res=0;
for (int i=1;i<=n;i++)
{
temp=ans[i]*l[i];
res=max(res,temp);
}
printf("%lld\n",res);
return 0;
}