Description
给定一棵 (n) 点树,边权为 (1)
对于每个点 (x) ,求出
[sum_{i=1}^n dis(x,i)^k
]
[nle 50000,kle 500
]
Solution
[n^k =sum_{i=0}^k inom n i imes S(k,i) imes i!
]
所以答案推一步就成了
[sum _ {i=1} ^n sum _ {j=0} ^k inom {dis(x,i)} j imes S(k,j) imes j!
]
[sum_{j=0}^k S(k,j) imes j! sum_{i=1}^n inom {dis(x,i)} j
]
所以我们要求啥?
[sum _ {j=0}^ksum _ {i=1}^n inom {dis(x,i)} j
]
这里组合数很难处理……如果转成距离统计空间会挂掉
这里有个 (trick) :杨辉三角
具体可以被写成:
[f[x][i]=f[t][i]+f[t][i-1]
]
Code
#include<bits/stdc++.h>
using namespace std;
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
const int N=50010,mod=10007;
struct node{
int to,nxt;
}e[N<<1];
int head[N],cnt,n,k;
inline void adde(int u,int v)
{
e[++cnt].to=v; e[cnt].nxt=head[u];
return head[u]=cnt,void();
}
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int del(int x,int y){return x-y>=0?x-y:x-y+mod;}
int f[N][510],s[510][510],fac[510];
inline void dfs1(int x,int fat)
{
for(int i=head[x];i;i=e[i].nxt)
{
int t=e[i].to; if(t==fat) continue; dfs1(t,x);
f[x][0]=add(f[x][0],f[t][0]);
for(int j=1;j<=k;++j) f[x][j]=add(f[x][j],add(f[t][j],f[t][j-1]));
} ++f[x][0];
return ;
}
inline void dfs2(int x,int fa)
{
for(int i=head[x];i;i=e[i].nxt)
{
int t=e[i].to; if(t==fa) continue;
for(int j=k;j>=1;--j)
{
int r1=del(f[x][j],add(f[t][j],f[t][j-1]));
int r2=del(f[x][j-1],add(f[t][j-1],j>=2?f[t][j-2]:0));
f[t][j]=add(f[t][j],add(r1,r2));
}
f[t][0]=add(f[t][0],del(f[x][0],f[t][0]));
dfs2(t,x);
} return ;
}
inline void work()
{
memset(e,0,sizeof(e)); memset(f,0,sizeof(f)); memset(head,0,sizeof(head)); cnt=0;
n=read(); k=read();
for(int i=1,u,v;i<n;++i) u=read(),v=read(),adde(u,v),adde(v,u);
dfs1(1,0); dfs2(1,0);
for(int i=1;i<=n;++i)
{
int ans=0;
for(int j=0;j<=k;++j) ans=add(ans,f[i][j]*fac[j]%mod*s[k][j]%mod);
cout<<ans<<endl;
} return ;
}
signed main()
{
s[1][1]=fac[0]=fac[1]=1; for(int i=1;i<=500;++i) s[i][1]=1,fac[i]=fac[i-1]*i%mod;
for(int i=2;i<=500;++i)
{
for(int j=2;j<=i;++j) s[i][j]=add(s[i-1][j-1],s[i-1][j]*j%mod);
}
int T=read(); while(T--) work();
return 0;
}
}
signed main(){return yspm::main();}