前言
csdn又更新了,然后版面还不好看
第二类斯特林数
根据我个人的经验,我觉得第一类斯特林数暂时没什么用
上面这句fake的话是不行的
所以这里只讨论第二类斯特林数
先是一般的递推式
S
(
n
,
k
)
=
S
(
n
−
1
,
k
−
1
)
+
S
(
n
−
1
,
k
)
∗
k
S(n,k)=S(n-1,k-1)+S(n-1,k)*k
S(n,k)=S(n−1,k−1)+S(n−1,k)∗k
然后也有单个求的
S
(
n
,
k
)
=
1
k
!
∑
i
=
0
k
(
−
1
)
i
∗
C
k
i
∗
(
m
−
k
)
n
S(n,k)=\frac{1}{k!}\sum_{i=0}^k{(-1)^i*C_k^i*(m-k)^n}
S(n,k)=k!1∑i=0k(−1)i∗Cki∗(m−k)n
然后一个比较常用的套路
因为我不会打下降幂,所以写成
f
(
x
)
f(x)
f(x)
x
n
=
∑
k
=
0
n
S
(
n
,
k
)
∗
x
f
(
k
)
x^n=\sum_{k=0}^n{S(n,k)*x^{f(k)}}
xn=∑k=0nS(n,k)∗xf(k)
然后还有一个技巧
就是
C
(
x
,
k
)
=
x
f
(
k
)
k
!
C(x,k)=\frac{x^{f(k)}}{k!}
C(x,k)=k!xf(k)
因此也可以写成
x
n
=
∑
k
=
0
n
S
(
n
,
k
)
∗
k
!
∗
C
(
x
,
k
)
x^n=\sum_{k=0}^nS(n,k)*k!*C(x,k)
xn=∑k=0nS(n,k)∗k!∗C(x,k)
一个题目
2159: Crash 的文明世界
就是用上面的式子展开一下就可以了。。
都是套路而已
我的题解
但应该也是可以自己推出来的吧。。
CODE:
#include<cstdio>
#include<cstring>
const int N=50005*2;
const int K=155;
const int MOD=10007;
int n,k;
struct qq
{
int x,y,last;
}e[N];int num,last[N];
void init (int x,int y)
{
num++;
e[num].x=x;e[num].y=y;
e[num].last=last[x];
last[x]=num;
}
int JC[N];
int s[K][K];
int f[N][K];
void DP (int x,int fa)
{
f[x][0]=1;
for (int u=last[x];u!=-1;u=e[u].last)
{
int y=e[u].y;
if (y==fa) continue;
DP(y,x);
f[x][0]=(f[x][0]+f[y][0])%MOD;
for (int i=1;i<=k;i++)
f[x][i]=(f[x][i]+(f[y][i]+f[y][i-1])%MOD)%MOD;
}
}
int ans[N];
int calc (int x,int y){return ((x-y)%MOD+MOD)%MOD;}
int g[K];
void dfs (int x,int fa)
{
for (int u=last[x];u!=-1;u=e[u].last)
{
int y=e[u].y;
if (y==fa) continue;
g[0]=calc(f[x][0],f[y][0]);
for (int i=1;i<=k;i++)
g[i]=calc(f[x][i],f[y][i]+f[y][i-1]);
f[y][0]=f[y][0]+g[0];
for (int i=1;i<=k;i++)
f[y][i]=(f[y][i]+g[i]+g[i-1])%MOD;
for (int i=1;i<=k;i++) ans[y]=(ans[y]+s[k][i]*JC[i]%MOD*f[y][i]%MOD)%MOD;
dfs(y,x);
}
}
int main()
{
num=0;memset(last,-1,sizeof(last));
int tL, tNOW, tA, tB, tC;
scanf("%d%d",&n,&k);
scanf("%d%d%d%d%d",&tL,&tNOW,&tA,&tB,&tC);
for (int u=1;u<n;u++)
{
int x,y;
//scanf("%d%d",&x,&y);
tNOW=(tNOW*tA+tB)%tC;
x=u-tNOW%(u<tL?u:tL),y=u+1;
init(x,y);init(y,x);
}
JC[0]=1;for (int u=1;u<=k;u++) JC[u]=JC[u-1]*u%MOD;
s[0][0]=1;
for (int u=1;u<=k;u++)
for (int i=1;i<=k;i++)
s[u][i]=(s[u-1][i-1]+s[u-1][i]*i%MOD)%MOD;
DP(1,0);
for (int u=1;u<=k;u++) ans[1]=(ans[1]+s[k][u]*JC[u]%MOD*f[1][u]%MOD)%MOD;
dfs(1,0);
for (int u=1;u<=n;u++) printf("%d\n",ans[u]);
return 0;
}