【总结】第一类和第二类斯特林数-cf960G&bzoj5093图的价值

本文总结了第一类和第二类斯特林数的概念及其关系,并通过CF960G和bzoj5093两道题目的解析展示了它们在解决递归计数问题中的应用。利用递推关系和生成函数,斯特林数可以用于快速计算特定排列和组合方案的数量,且可以通过FFT优化求解效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考资料:
第一类斯特林数求自然数幂和学习小记
第二类斯特林数 学习总结
第一和第二类斯特林数小结
具体数学·斯特林数


第一类斯特林数

[ 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]=[n1k1]+(n1)[n1k]

生成函数: ∏ i = 0 n − 1 ( x + i ) \prod \limits_{i=0}^{n-1}(x+i) i=0n1(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=0n[nk]
因为对于一个 1 − n 1-n 1n的排列 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 1n的排列 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 n105,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(n1)之间选择 A − 1 A-1 A1个并在 ( n + 1 ) − a n (n+1)-a_n (n+1)an之间选择 B − 1 B-1 B1个满足上述要求的数( a 1 , a n a_1,a_n a1,an包含在内)。

本质上就是把 n − 1 n-1 n1个数(没有考虑 n n n)划分成 A + B − 2 A+B-2 A+B2个非空集合,任选 A − 1 A-1 A1个集合放在 n n n左边,剩下 B − 1 B-1 B1个放在 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=[n1A+B2](A1A+B2)

代码(含分治 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}={n1k1}+k{n1k}

因为系数和 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=0k(1)i(ik)(ki)n
容斥:假设是将 n n n个标号不同的球放进 k k k个盒子里,每次枚举不能选(最少不选)的盒子数(选择的盒子有 ( k i ) \binom k i (ik)种组合),再将 n n n个球分别放入可以选的盒子里( ( k − i ) n (k-i)^n (ki)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=0ki!(1)i(ki)(ki)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(x1)...(xk+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=0n{ni}xi=i=0n{ni}(ix)i!(nN)

本质上就是枚举把 n n n个不同的球放到 0 − n 0-n 0n个不同的盘子里,可以用归纳法证明:
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(xi),所以 x ⋅ x i ‾ = x i + 1 ‾ + i x i ‾ x·x^{\underline i}=x^{\underline {i+1}}+ix^{\underline i} xxi=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=0n1{n1i}xi=i=0n1{n1i}xi+1+i=0n1{n1i}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=1n{n1i1}xi+i=0n1{n1i}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=0n({n1i1}+i{n1i})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=0n{ni}xi

例题:bzoj5093: [Lydsy1711月赛]图的价值

题意:
一个带标号的图的价值定义为每个点度数的k次方的和。
给定n和k,请计算所有n个点的带标号的简单无向图的价值之和。
n ≤ 1 0 9 , k ≤ 2 × 1 0 5 , m o d &ThinSpace;&ThinSpace; 998244353 n\leq10^9,k\leq2\times10^5,\mod {998244353} n109,k2×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(n1)(n2)i=0n1ik(in1)

n n n表示 n − 1 n-1 n1,并将 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(n1)j=0k{kj}j!i=jn(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=jn(in)(ji)=i=jnj!(ij)!(ni)!n!=(jn)i=jn(ijnj)=(jn)2nj

所以 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(n1)j=0k{kj}j!(jn)2nj

代码(含 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]={kn}k,nZ

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(x1)(x2)(x3),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=0n{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=0n{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=0n{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=0n{ni}(1)niA(x,i)


推荐题目

第二类斯特林数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值