参考资料:
第一类斯特林数求自然数幂和学习小记
第二类斯特林数 学习总结
第一和第二类斯特林数小结
具体数学·斯特林数
第一类斯特林数
[ n k ] \left[ \begin{matrix} n\\k\end{matrix} \right] [nk]指将 n n n个不同的元素排成 k k k个轮换方案数。
递推式: [ n k ] = [ n − 1 k − 1 ] + ( n − 1 ) [ n − 1 k ] \left[ \begin{matrix} n\\k\end{matrix} \right]=\left[ \begin{matrix} n-1\\k-1\end{matrix} \right]+(n-1)\left[ \begin{matrix} n-1\\k\end{matrix} \right] [nk]=[n−1k−1]+(n−1)[n−1k]
生成函数:
∏
i
=
0
n
−
1
(
x
+
i
)
\prod \limits_{i=0}^{n-1}(x+i)
i=0∏n−1(x+i)
其第
k
k
k项(
x
k
x^k
xk)的系数即为
[
n
k
]
\left[ \begin{matrix} n\\k\end{matrix} \right]
[nk]
使用分治
F
F
T
FFT
FFT可以
O
(
n
l
o
g
2
n
)
O(nlog^2n)
O(nlog2n)求解
与阶乘的关系:
n
!
=
∑
k
=
0
n
[
n
k
]
n!=\sum_{k=0}^n\left[ \begin{matrix} n\\k\end{matrix} \right]
n!=k=0∑n[nk]
因为对于一个
1
−
n
1-n
1−n的排列
P
P
P,每一种排列方式都对应着一个轮换的集合(从群论(
p
o
l
y
a
/
b
u
r
n
s
i
d
e
polya/burnside
polya/burnside)中可以感受到排列和轮换安排本质上的相同)。
例题:CF960G
题意:
给定 n , A , B n,A,B n,A,B,求有多少个 1 − n 1-n 1−n的排列 P = a 1 , a 2 , . . , a n P={a_1,a_2,..,a_n} P=a1,a2,..,an满足从 a 1 a_1 a1开始向右的最长递增序列长度为 A A A且从 a n a_n an开始向左的最长递增序列长度为 B B B。 n ≤ 1 0 5 , m o d    998244353 n\leq10^5,\mod 998244353 n≤105,mod998244353
题解:
一个数被选中的要求是它前面(从 a n a_n an开始就是后面)没有比它大的数。
无论从 a 1 a_1 a1还是从 a n a_n an开始,最后都在值为 n n n处结束,所以 n n n将 a 1 a_1 a1和 a n a_n an的递增数列截断了,问题转化成了在 a 1 − ( n − 1 ) a_1-(n-1) a1−(n−1)之间选择 A − 1 A-1 A−1个并在 ( n + 1 ) − a n (n+1)-a_n (n+1)−an之间选择 B − 1 B-1 B−1个满足上述要求的数( a 1 , a n a_1,a_n a1,an包含在内)。
本质上就是把 n − 1 n-1 n−1个数(没有考虑 n n n)划分成 A + B − 2 A+B-2 A+B−2个非空集合,任选 A − 1 A-1 A−1个集合放在 n n n左边,剩下 B − 1 B-1 B−1个放在 n n n右边,按每个集合中的最大数升序排列后就保证了每个集合必然会选择一个,符合了要求。
则 a n s = [ n − 1 A + B − 2 ] ( A + B − 2 A − 1 ) ans=\left[ \begin{matrix} n-1\\A+B-2\end{matrix} \right]\binom{A+B-2}{A-1} ans=[n−1A+B−2](A−1A+B−2)
代码(含分治 F F T FFT FFT求解第一类斯特林数):
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353,g=3,N=5e5+10;
typedef long long ll;
int n,x,y,nv[200010],a[19][N],rv[N],len,L,ivg;
inline int ad(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int dc(int x,int y){x-=y;return x<0?x+mod:x;}
inline int fp(int x,int y)
{
if(!x) return 0;
int re=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1) re=(ll)re*x%mod;
return re;
}
inline void ntt(int *e,int pr)
{
int i,j,k,ix,iy,ori,pd,G=pr?g:ivg;
for(i=1;i<len;++i) if(i<rv[i]) swap(e[i],e[rv[i]]);
for(i=1;i<len;i<<=1){
ori=fp(G,(mod-1)/(i<<1));
for(j=0;j<len;j+=(i<<1)){
pd=1;
for(k=0;k<i;++k,pd=(ll)pd*ori%mod){
ix=e[j+k];iy=(ll)pd*e[i+j+k]%mod;
e[j+k]=ad(ix,iy);e[i+j+k]=dc(ix,iy);
}
}
}
if(pr) return;
G=fp(len,mod-2);
for(i=0;i<len;++i) e[i]=(ll)e[i]*G%mod;
}
void sol(int l,int r,int d)
{
if(l==r){a[d][0]=l;a[d][1]=1;return;}
int i,j,lim,mid=(l+r)>>1;sol(l,mid,d+1);
lim=mid-l+1;memcpy(a[d],a[d+1],sizeof(int)*(lim+1));
sol(mid+1,r,d+1);
for(len=1,L=0,lim=r-l+1;len<=lim;len<<=1) L++;
for(i=1;i<len;++i) rv[i]=((rv[i>>1]>>1)|((i&1)<<(L-1)));
for(i=mid-l+2;i<len;++i) a[d][i]=0;
for(i=r-mid+1;i<len;++i) a[d+1][i]=0;
ntt(a[d],1);ntt(a[d+1],1);
for(i=0;i<len;++i) a[d][i]=(ll)a[d][i]*a[d+1][i]%mod;
ntt(a[d],0);
}
int main(){
int i,C=1,lim;nv[0]=nv[1]=1;
scanf("%d%d%d",&n,&x,&y);ivg=fp(g,mod-2);
if((n-1<x+y-2)||(!x)||(!y)) {puts("0");return 0;}
if(n==1) {puts("1");return 0;}
sol(0,n-2,0);lim=x+y-2;x=min(x,y);
for(i=2;i<x;++i) nv[i]=(ll)(mod-mod/i)*nv[mod%i]%mod;
for(i=1;i<x;++i) C=(ll)C*(lim-i+1)%mod*(ll)nv[i]%mod;
printf("%d",(ll)C*a[0][lim]%mod);
return 0;
}
第二类斯特林数
{ n k } \left \{ \begin{matrix} n\\k\end{matrix} \right \} {nk}表示将 n n n个不同的元素划分成 k k k个非空集合的方案数。
递推式: { n k } = { n − 1 k − 1 } + k { n − 1 k } \left \{ \begin{matrix} n\\k\end{matrix} \right \}=\left \{ \begin{matrix} n-1\\k-1\end{matrix} \right \}+k\left \{ \begin{matrix} n-1\\k\end{matrix} \right \} {nk}={n−1k−1}+k{n−1k}
因为系数和
k
k
k有关,没有生成函数,但存在通项公式:
{
n
k
}
=
1
k
!
∑
i
=
0
k
(
−
1
)
i
(
k
i
)
(
k
−
i
)
n
\left \{ \begin{matrix} n\\k\end{matrix} \right \}=\dfrac1{k!}\sum\limits_{i=0}^k(-1)^i\binom{k}{i}(k-i)^n
{nk}=k!1i=0∑k(−1)i(ik)(k−i)n
容斥:假设是将
n
n
n个标号不同的球放进
k
k
k个盒子里,每次枚举不能选(最少不选)的盒子数(选择的盒子有
(
k
i
)
\binom k i
(ik)种组合),再将
n
n
n个球分别放入可以选的盒子里(
(
k
−
i
)
n
(k-i)^n
(k−i)n),最后除以盒子的排列数
k
!
k!
k!。
上式可以转化成卷积形式:
∑
i
=
0
k
(
−
1
)
i
i
!
(
k
−
i
)
n
(
k
−
i
)
!
\sum\limits_{i=0}^k\dfrac{(-1)^i}{i!}\dfrac{(k-i)^n}{(k-i)!}
i=0∑ki!(−1)i(k−i)!(k−i)n
使用
F
F
T
FFT
FFT可以
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)求解。
设 x k ‾ = x ( x − 1 ) . . . ( x − k + 1 ) x^{\underline k}=x(x-1)...(x-k+1) xk=x(x−1)...(x−k+1),即 x x x的 k k k阶下降幂。
与通常幂的关系: x n = ∑ i = 0 n { n i } x i ‾ = ∑ i = 0 n { n i } ( x i ) i ! ( n ∈ N ) x^n=\sum\limits_{i=0}^n\left \{ \begin{matrix} n\\i\end{matrix} \right \}x^{\underline{i}}=\sum\limits_{i=0}^n\left \{ \begin{matrix} n\\i\end{matrix} \right \}\binom{x}{i}i!\qquad (n\in N) xn=i=0∑n{ni}xi=i=0∑n{ni}(ix)i!(n∈N)
本质上就是枚举把
n
n
n个不同的球放到
0
−
n
0-n
0−n个不同的盘子里,可以用归纳法证明:
x
0
=
1
x^0=1
x0=1
因为 x i + 1 ‾ = x i ‾ ( x − i ) x^{\underline {i+1}}=x^{\underline i}(x-i) xi+1=xi(x−i),所以 x ⋅ x i ‾ = x i + 1 ‾ + i x i ‾ x·x^{\underline i}=x^{\underline {i+1}}+ix^{\underline i} x⋅xi=xi+1+ixi。
则
x
∑
i
=
0
n
−
1
{
n
−
1
i
}
x
i
‾
=
∑
i
=
0
n
−
1
{
n
−
1
i
}
x
i
+
1
‾
+
∑
i
=
0
n
−
1
{
n
−
1
i
}
i
x
i
‾
x\sum\limits_{i=0}^{n-1}\left \{ \begin{matrix} n-1\\i\end{matrix} \right \}x^{\underline i}=\sum\limits_{i=0}^{n-1}\left \{ \begin{matrix} n-1\\i\end{matrix} \right \}x^{\underline {i+1}}+\sum\limits_{i=0}^{n-1}\left \{ \begin{matrix} n-1\\i\end{matrix} \right \}ix^{\underline i}
xi=0∑n−1{n−1i}xi=i=0∑n−1{n−1i}xi+1+i=0∑n−1{n−1i}ixi
∑
i
=
1
n
{
n
−
1
i
−
1
}
x
i
‾
+
∑
i
=
0
n
−
1
{
n
−
1
i
}
i
x
i
‾
\qquad \qquad \qquad \qquad \ \ \sum\limits_{i=1}^{n}\left \{ \begin{matrix} n-1\\i-1\end{matrix} \right \}x^{\underline i}+\sum\limits_{i=0}^{n-1}\left \{ \begin{matrix} n-1\\i\end{matrix} \right \}ix^{\underline i}
i=1∑n{n−1i−1}xi+i=0∑n−1{n−1i}ixi
∑
i
=
0
n
(
{
n
−
1
i
−
1
}
+
i
{
n
−
1
i
}
)
x
i
‾
\qquad \qquad \qquad \qquad \ \ \sum\limits_{i=0}^{n}(\left \{ \begin{matrix} n-1\\i-1\end{matrix} \right \}+i\left \{ \begin{matrix} n-1\\i\end{matrix} \right \})x^{\underline i}
i=0∑n({n−1i−1}+i{n−1i})xi
∑
i
=
0
n
{
n
i
}
x
i
‾
\qquad \qquad \qquad \qquad \ \ \sum\limits_{i=0}^n\left \{ \begin{matrix} n\\i\end{matrix} \right \}x^{\underline{i}}
i=0∑n{ni}xi
例题:bzoj5093: [Lydsy1711月赛]图的价值
题意:
一个带标号的图的价值定义为每个点度数的k次方的和。
给定n和k,请计算所有n个点的带标号的简单无向图的价值之和。
n
≤
1
0
9
,
k
≤
2
×
1
0
5
,
m
o
d
  
998244353
n\leq10^9,k\leq2\times10^5,\mod {998244353}
n≤109,k≤2×105,mod998244353
题解:
枚举单个点的度数对于所有简单无向图的贡献: a n s = n × 2 ( n − 1 ) ( n − 2 ) 2 ∑ i = 0 n − 1 i k ( n − 1 i ) ans=n\times2^{\frac{(n-1)(n-2)}{2}}\sum_{i=0}^{n-1}i^k\binom{n-1}{i} ans=n×22(n−1)(n−2)i=0∑n−1ik(in−1)
用
n
n
n表示
n
−
1
n-1
n−1,并将
i
k
i^k
ik转成第二类斯特林数得到:
(
n
+
1
)
2
n
(
n
−
1
)
2
∑
j
=
0
k
{
k
j
}
j
!
∑
i
=
j
n
(
n
i
)
(
i
j
)
(n+1)2^{\frac{n(n-1)}{2}}\sum\limits_{j=0}^k\left \{ \begin{matrix} k\\j\end{matrix} \right \}j!\sum\limits_{i=j}^n\dbinom{n}{i}\dbinom ij
(n+1)22n(n−1)j=0∑k{kj}j!i=j∑n(in)(ji)
其中: ∑ i = j n ( n i ) ( i j ) = ∑ i = j n n ! j ! ( i − j ) ! ( n − i ) ! = ( n j ) ∑ i = j n ( n − j i − j ) = ( n j ) 2 n − j \sum\limits_{i=j}^n\dbinom{n}{i}\dbinom ij=\sum\limits_{i=j}^n\dfrac{n!}{j!(i-j)!(n-i)!}=\dbinom{n}{j}\sum_{i=j}^n\dbinom{n-j}{i-j}=\dbinom{n}{j}2^{n-j} i=j∑n(in)(ji)=i=j∑nj!(i−j)!(n−i)!n!=(jn)∑i=jn(i−jn−j)=(jn)2n−j
所以 a n s = ( n + 1 ) 2 n ( n − 1 ) 2 ∑ j = 0 k { k j } j ! ( n j ) 2 n − j ans=(n+1)2^{\frac{n(n-1)}{2}}\sum\limits_{j=0}^k\left \{ \begin{matrix} k\\j\end{matrix} \right \}j!\dbinom{n}{j}2^{n-j} ans=(n+1)22n(n−1)j=0∑k{kj}j!(jn)2n−j
代码(含 F F T FFT FFT求解第二类斯特林数):
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353,g=3,N=5e6+10;
typedef long long ll;
int n,m,frac,nv[200010],fnv[200010];
int rv[N],a[N],b[N],ans,ivg,len,L;
inline int ad(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int dc(int x,int y){x-=y;return x<0?x+mod:x;}
inline int fp(int x,int y)
{
if(!x) return 0;
int re=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1) re=(ll)re*x%mod;
return re;
}
inline void ntt(int *e,int pr)
{
int i,j,k,ix,iy,ori,pd,G=pr?g:ivg;
for(i=1;i<len;++i) if(i<rv[i]) swap(e[i],e[rv[i]]);
for(i=1;i<len;i<<=1){
ori=fp(G,(mod-1)/(i<<1));
for(j=0;j<len;j+=(i<<1)){
pd=1;
for(k=0;k<i;++k,pd=(ll)pd*ori%mod){
ix=e[j+k];iy=(ll)pd*e[i+j+k]%mod;
e[j+k]=ad(ix,iy);e[i+j+k]=dc(ix,iy);
}
}
}
if(pr) return;
G=fp(len,mod-2);
for(i=0;i<len;++i) e[i]=(ll)e[i]*G%mod;
}
int main(){
int i,j,lim,C;
scanf("%d%d",&n,&m);n--;ivg=fp(g,mod-2);
fnv[0]=fnv[1]=nv[0]=nv[1]=1;
for(i=2;i<=m;++i) nv[i]=(ll)(mod-mod/i)*nv[mod%i]%mod;
for(i=2;i<=m;++i) fnv[i]=(ll)fnv[i-1]*nv[i]%mod;
for(i=0;i<=m;++i)
a[i]=(i&1)?(mod-fnv[i]):fnv[i],b[i]=(ll)fp(i,m)*fnv[i]%mod;
for(len=1;len<=m+m;len<<=1) L++;
for(i=1;i<len;++i) rv[i]=((rv[i>>1]>>1)|((i&1)<<(L-1)));
ntt(a,1);ntt(b,1);
for(i=0;i<len;++i) a[i]=(ll)a[i]*b[i]%mod;
ntt(a,0);
lim=min(n,m);
for(C=frac=1,i=0;i<=lim;++i){
ans=ad(ans,(ll)a[i]*frac%mod*(ll)C%mod*(ll)fp(2,n-i)%mod);
C=(ll)C*(n-i)%mod*(ll)nv[i+1]%mod;frac=(ll)frac*(i+1)%mod;
}
printf("%d",(ll)(n+1)*fp(2,((ll)n*(n-1)/2LL)%(mod-1))%mod*(ll)ans%mod);
return 0;
}
二者的关系
一种类似于“对偶性”的关系。
[
n
k
]
=
{
−
k
−
n
}
k
,
n
∈
Z
\left[ \begin{matrix} n\\k\end{matrix} \right]=\left \{ \begin{matrix} -k\\-n\end{matrix} \right \}\qquad k,n\in Z
[nk]={−k−n}k,n∈Z
设
A
(
x
,
n
)
A(x,n)
A(x,n)表示
x
x
x的
n
n
n次上升幂。
又上升幂和下降幂的转化:
x
n
‾
=
(
−
1
)
n
A
(
−
x
,
n
)
x^{\underline n}=(-1)^nA(-x,n)
xn=(−1)nA(−x,n)
如 x 4 ‾ = x ( x − 1 ) ( x − 2 ) ( x − 3 ) , A ( − x , 4 ) = ( − x ) ( − x + 1 ) ( − x + 2 ) ( − x + 3 ) x^{\underline 4}=x(x-1)(x-2)(x-3),A(-x,4)=(-x)(-x+1)(-x+2)(-x+3) x4=x(x−1)(x−2)(x−3),A(−x,4)=(−x)(−x+1)(−x+2)(−x+3)
那么
x
n
=
∑
i
=
0
n
{
n
i
}
x
i
‾
x^n=\sum\limits_{i=0}^n\left \{ \begin{matrix} n\\i\end{matrix} \right \}x^{\underline i}
xn=i=0∑n{ni}xi可以转化为:
(
−
x
)
n
=
∑
i
=
0
n
{
n
i
}
(
−
x
)
i
‾
(-x)^n=\sum\limits_{i=0}^n\left \{ \begin{matrix} n\\i\end{matrix} \right \}(-x)^{\underline i}
(−x)n=i=0∑n{ni}(−x)i
所以:
(
−
1
)
n
x
n
=
∑
i
=
0
n
{
n
i
}
(
−
1
)
i
A
(
x
,
i
)
(-1)^nx^n=\sum\limits_{i=0}^n\left \{ \begin{matrix} n\\i\end{matrix} \right \}(-1)^iA(x,i)
(−1)nxn=i=0∑n{ni}(−1)iA(x,i),即通常幂可以用上升幂表示:
x
n
=
∑
i
=
0
n
{
n
i
}
(
−
1
)
n
−
i
A
(
x
,
i
)
x^n=\sum\limits_{i=0}^n\left \{ \begin{matrix} n\\i\end{matrix} \right \}(-1)^{n-i}A(x,i)
xn=i=0∑n{ni}(−1)n−iA(x,i)
推荐题目
第二类斯特林数