#include<bits/stdc++.h>
#define int long long int
using namespace std;
int n,k,s[100010],sum[100010][30],fa[100010];
vector<int> e[100010];
void dfs(int p)
{
for(int i=0;i<=k;i++) sum[p][i]=s[p];
for(int i=0;i<e[p].size();i++)
{
int v=e[p][i];
if(v!=fa[p])
{
fa[v]=p;
dfs(v);
for(int j=1;j<=k;j++) sum[p][j]+=sum[v][j-1];
}
}
}
signed main()
{
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n-1;i++)
{
int u,v;
scanf("%lld%lld",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
for(int i=1;i<=n;i++) scanf("%lld",&s[i]);
dfs(1);
for(int i=1;i<=n;i++)
{
int len=k,ans=0,p=i,f=fa[i];
ans+=sum[i][len];
while(len--&&f!=0)
{
ans+=sum[f][0];
if(len)
{
for(int j=0;j<e[f].size();j++)
{
int v=e[f][j];
if(v!=fa[f]&&v!=p) ans+=sum[v][len-1];
}
}
p=f;
f=fa[p];
}
printf("%lld\n",ans);
}
}
大概思路是把这棵树当做以点1为根,然后预处理数组sum[i][j]存储点i的子树中所有节点(包括点i自己)中距离点i不大于k的所有点的权值和。在求解过程中先加上sum[i][k],然后向父亲节点上溯到根节点(或距离i超过k时跳出),用同样的方法统计结果。T了#3,求调