其中
{
n
m
}
\begin{Bmatrix}n\\m\end{Bmatrix}
{nm} 为第二类斯特林数,即
n
n
n 个元素划分成
m
m
m 个无序非空集合的方案数,
(
n
m
)
\binom nm
(mn) 为组合数 ,即
n
n
n 个元素中选出
m
m
m 个无序元素的方案数
把式子化一下
∑
j
=
1
n
d
i
s
t
(
i
,
j
)
k
=
∑
j
=
1
n
∑
h
=
0
k
{
k
h
}
×
(
d
i
s
t
(
i
,
j
)
h
)
×
h
!
\sum_{j=1}^ndist(i,j)^k=\sum_{j=1}^n\sum_{h=0}^k\begin{Bmatrix}k\\h\end{Bmatrix}\times\binom{dist(i,j)}h\times h!
j=1∑ndist(i,j)k=j=1∑nh=0∑k{kh}×(hdist(i,j))×h!
=
∑
h
=
0
k
{
k
h
}
×
h
!
×
∑
j
=
1
n
(
d
i
s
t
(
i
,
j
)
h
)
=\sum_{h=0}^k\begin{Bmatrix}k\\h\end{Bmatrix}\times h!\times\sum_{j=1}^n\binom{dist(i,j)}h
=h=0∑k{kh}×h!×j=1∑n(hdist(i,j))
于是我们要求的就是对于每个
1
≤
u
≤
n
1\le u\le n
1≤u≤n ,
0
≤
i
≤
k
0\le i\le k
0≤i≤k ,求
∑
v
=
1
n
(
d
i
s
t
(
u
,
v
)
i
)
\sum_{v=1}^n\binom{dist(u,v)}i
v=1∑n(idist(u,v))
我们的状态出来了
f
[
u
]
[
i
]
f[u][i]
f[u][i] 表示
u
u
u 到
u
u
u 的子树内的所有点的距离,的
(
d
i
s
t
i
)
\binom{dist}i
(idist) 之和
根据优美的组合数公式
(
n
m
)
=
(
n
−
1
m
)
+
(
n
−
1
m
−
1
)
\binom nm=\binom{n-1}m+\binom{n-1}{m-1}
(mn)=(mn−1)+(m−1n−1) 得到
f
[
u
]
[
i
]
=
∑
v
∈
s
u
b
s
t
r
e
e
[
u
]
(
d
i
s
t
(
u
,
v
)
i
)
f[u][i]=\sum_{v\in substree[u]}\binom{dist(u,v)}i
f[u][i]=v∈substree[u]∑(idist(u,v))
=
∑
v
∈
s
u
b
s
t
r
e
e
[
u
]
(
(
d
i
s
t
(
u
,
v
)
−
1
i
)
+
(
d
i
s
t
(
u
,
v
)
−
1
i
−
1
)
)
=\sum_{v\in substree[u]}(\binom{dist(u,v)-1}i+\binom{dist(u,v)-1}{i-1})
=v∈substree[u]∑((idist(u,v)−1)+(i−1dist(u,v)−1))
=
[
i
=
0
]
+
∑
v
∈
s
o
n
[
u
]
(
f
[
v
]
[
i
]
+
f
[
v
]
[
i
−
1
]
)
=[i=0]+\sum_{v\in son[u]}(f[v][i]+f[v][i-1])
=[i=0]+v∈son[u]∑(f[v][i]+f[v][i−1])
然而我们要求的不仅仅是源点为
1
1
1 的答案,故我们还需要换根
g
[
u
]
[
i
]
g[u][i]
g[u][i] 表示
u
u
u 到整棵树除了
u
u
u 的子树之外的所有点的距离,的
(
d
i
s
t
i
)
\binom{dist}i
(idist) 之和
转移和
f
f
f 差不多,注意计算
g
[
f
a
t
h
e
r
[
u
]
]
g[father[u]]
g[father[u]] 时需要消除
f
[
u
]
f[u]
f[u] 的影响
复杂度
O
(
n
k
)
O(nk)
O(nk) 非常优秀
Code
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define For(i, a, b) for (i = a; i <= b; i++)#define Tree(u) for (int e = adj[u], v; e; e = nxt[e]) if ((v = go[e]) != fu)inlineintread(){int res =0;bool bo =0;char c;while(((c =getchar())<'0'|| c >'9')&& c !='-');if(c =='-') bo =1;else res = c -48;while((c =getchar())>='0'&& c <='9')
res =(res <<3)+(res <<1)+(c -48);return bo ?~res +1: res;}constint N =5e4+5, M = N <<1, E =155, ZZQ =10007;int n, k, ecnt, nxt[M], adj[N], go[M], f[N][E], g[N][E], S[E][E], fac[E];voidadd_edge(int u,int v){
nxt[++ecnt]= adj[u]; adj[u]= ecnt; go[ecnt]= v;
nxt[++ecnt]= adj[v]; adj[v]= ecnt; go[ecnt]= u;}voiddfs1(int u,int fu){int i;
f[u][0]=1;Tree(u){dfs1(v, u);
f[u][0]+= f[v][0];
For (i,1, k)
f[u][i]=(f[u][i]+ f[v][i]+ f[v][i -1])% ZZQ;}}voiddfs2(int u,int fu){int i;
For (i,0, k){int tmp =(g[u][i]+(i ? g[u][i -1]:0))% ZZQ;Tree(u) tmp =(tmp + f[v][i]+(i ? f[v][i -1]:0))% ZZQ;Tree(u) g[v][i]=(tmp - f[v][i]-(i ? f[v][i -1]:0)+ ZZQ + ZZQ +(!i))% ZZQ;}Tree(u)dfs2(v, u);}intmain(){int i, j, x, y, L, now, A, B, Q;
n =read(); k =read(); L =read(); now =read(); A =read();
B =read(); Q =read();
For (i,1, n -1){
now =(now * A + B)% Q;int tmp = i < L ? i : L;
x = i - now % tmp; y = i +1;add_edge(x, y);}
S[0][0]= fac[0]=1;
For (i,1, k) fac[i]=1ll* fac[i -1]* i % ZZQ;
For (i,1, k) For (j,1, i)
S[i][j]=(S[i -1][j -1]+ j * S[i -1][j])% ZZQ;dfs1(1,0);dfs2(1,0);
For (i,1, n){int ans =0;
For (j,0, k)
ans =(S[k][j]* fac[j]% ZZQ *(f[i][j]+ g[i][j]+(j ? g[i][j -1]:0))+ ans)% ZZQ;printf("%d\n", ans);}return0;}