• [USACO12FEB] 附近的牛 Nearby Cows


    给你一棵 (n) 个点的树,点带权,对于每个节点求出距离它不超过 (k) 的所有节点权值和 (m_i)

    随便定一个根,设(f[i][j])表示只考虑子树,距离为(j)的权值和,(g[i][j])表示考虑子树和父树,距离为(j)的权值和,显然答案可以用(g)表示

    (f[p][0]=w[p])
    (f[p][k]=sum f[q][k-1])
    (g[1][k]=f[1][k])
    (g[p][0]=w[p])

    (g)的计算,考虑容斥

    [g[q][k] =sum( f[q][k] + g[p][k-1] - f[q][k-2]) ]

    注意特判掉(k=1)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 100005;
    vector <int> G[N];
    int n,k,vis[N],f[N][22],g[N][22],w[N];
    
    void dfs1(int p) {
        vis[p]=1;
        for(int i=0;i<G[p].size();i++) {
            int q=G[p][i];
            if(vis[q]) continue;
            dfs1(q);
            for(int j=1;j<=k;j++)
                f[p][j]+=f[q][j-1];
        }
    }
    
    void dfs2(int p) {
        vis[p]=1;
        for(int i=0;i<G[p].size();i++) {
            int q=G[p][i];
            if(vis[q]) continue;
            for(int j=1;j<=k;j++)
                g[q][j]+=f[q][j]+g[p][j-1]-(j>1?1:0)*f[q][j-2];
            dfs2(q);
        }
    }
    
    signed main() {
        scanf("%lld%lld",&n,&k);
        for(int i=1;i<n;i++) {
            int t1,t2;
            scanf("%lld%lld",&t1,&t2);
            G[t1].push_back(t2);
            G[t2].push_back(t1);
        }
        for(int i=1;i<=n;i++) scanf("%lld",&w[i]);
        for(int i=1;i<=n;i++) f[i][0]=g[i][0]=w[i];
        dfs1(1);
        for(int i=1;i<=k;i++) g[1][i]=f[1][i];
        memset(vis,0,sizeof vis);
        dfs2(1);
        for(int i=1;i<=n;i++) {
            int ans = 0;
            for(int j=0;j<=k;j++) ans+=g[i][j];
            printf("%lld
    ",ans);
        }
    }
    
  • 相关阅读:
    SQL Server 文件操作
    约束5:外键约束
    SSIS 对数据排序
    列属性:RowGUIDCol、Identity 和 not for replication
    TSQL 数据类型转换
    HierarchyID 数据类型用法
    租房那些事
    SSIS 延迟验证
    SQL Server 管理全文索引
    SQL Server 全文搜索
  • 原文地址:https://www.cnblogs.com/mollnn/p/12257474.html
Copyright © 2020-2023  润新知