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;
}

posted @ 2019-09-27 21:16  Minun  阅读(120)  评论(0编辑  收藏  举报