分析
a
n
s
(
x
)
=
∑
i
=
1
n
∑
j
=
0
k
S
(
k
,
j
)
j
!
C
d
i
s
(
i
,
x
)
j
ans(x)=\sum_{i=1}^n\sum_{j=0}^kS(k,j)j!C_{dis(i,x)}^j
ans(x)=i=1∑nj=0∑kS(k,j)j!Cdis(i,x)j
=
∑
j
=
0
k
S
(
k
,
j
)
j
!
∑
i
=
1
n
C
d
i
s
(
i
,
x
)
−
1
j
+
C
d
i
s
(
i
,
x
)
−
1
j
−
1
=\sum_{j=0}^kS(k,j)j!\sum_{i=1}^nC_{dis(i,x)-1}^j+C_{dis(i,x)-1}^{j-1}
=j=0∑kS(k,j)j!i=1∑nCdis(i,x)−1j+Cdis(i,x)−1j−1
这就可以dp了,但是这仅仅是根,所以要换根,时间复杂度
O
(
n
)
O(n)
O(n)
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
const int N=50011,mod=10007;
struct node{int y,next;}e[N<<1];
int ls[N],f[N][151],dp[N][151],t[151],k=1,n,m,stir[151][151],fac[151];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void add(int x,int y){
e[++k]=(node){y,ls[x]},ls[x]=k,
e[++k]=(node){x,ls[y]},ls[y]=k;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline void dfs1(int x,int fa){
f[x][0]=1;
for (rr int i=ls[x];i;i=e[i].next)
if (e[i].y!=fa){
dfs1(e[i].y,x);
for (rr int j=1;j<=m;++j) f[x][j]=mo(f[x][j],mo(f[e[i].y][j],f[e[i].y][j-1]));
f[x][0]=mo(f[x][0],f[e[i].y][0]);
}
}
inline void dfs2(int x,int fa){
for (rr int i=0;i<=m;++i) dp[x][i]=f[x][i];
if (fa){
for (rr int i=1;i<=m;++i) t[i]=mo(dp[fa][i]-mo(f[x][i],f[x][i-1]),mod);
t[0]=mo(dp[fa][0]-f[x][0],mod);
for (rr int i=1;i<=m;++i) dp[x][i]=mo(dp[x][i],mo(t[i],t[i-1]));
dp[x][0]=mo(dp[x][0],t[0]);
}
for (rr int i=ls[x];i;i=e[i].next)
if (e[i].y!=fa) dfs2(e[i].y,x);
}
signed main(){
n=iut(); m=iut();
fac[0]=fac[1]=stir[0][0]=stir[1][1]=1;
for (rr int i=2;i<=m;++i){
fac[i]=fac[i-1]*i%mod;
for (rr int j=1;j<=i;++j)
stir[i][j]=mo(stir[i-1][j-1],j*stir[i-1][j]%mod);
}
for (rr int i=1;i<n;++i) add(iut(),iut());
dfs1(1,0),dfs2(1,0);
for (rr int i=1;i<=n;++i){
rr int ans=0;
for (rr int j=0;j<=m;++j) ans=mo(ans,stir[m][j]*fac[j]%mod*dp[i][j]%mod);
print(ans),putchar(10);
}
return 0;
}