No Link, Cut Tree! Gym - 101484F(dp)
dp[i][j]代表在i为根 深度为j时的价值河
所以 dp[i][j]=dp[i2][j-1]+dp[i2+1][j-1]
重新标一下号 开始跑转移方程即可
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=5e5+10;
int dp[maxn][35],D[maxn];
int has[maxn],v[maxn];
struct node{
int l,r;
}tree[maxn];
int d=0,tot=0;
void dfs(int now,int u,int dep)
{
if(u==-1) return ;
d=max(d,dep);
tot=max(tot,now);
D[now]=dep;
has[u]=now;
dp[now][1]=v[u];
dfs(now*2,tree[u].l,dep+1);
dfs(now*2+1,tree[u].r,dep+1);
}
int main(){
int n,m;
cin>>n>>m>>v[1];
for(int i=1;i<=n;i++) tree[i].l=tree[i].r=-1;
for(int i=1;i<n;i++)
{
int son,f;
cin>>son>>f;cin>>v[son];
if(tree[f].l==-1) tree[f].l=son;
else tree[f].r=son;
}
dfs(1,1,1);
for(int i=tot;i>=1;i--)
{
for(int j=d;j>=2;j--)
{
dp[i][j]=dp[i*2][j-1]+dp[i*2+1][j-1];
}
}
while(m--)
{
int now,ans=0;
cin>>now;
now=has[now];
for(int i=1;i<=d;i++)
{
if(i<D[now])
{
ans=max(ans,dp[1][i]);
}
else
{
ans=max(ans,dp[1][i]-dp[now][i-D[now]+1]);
}
}
cout<<ans<<"\n";
}
return 0;
}