第二类斯特林数学习笔记 /CF1278F Cards 题解

第二类斯特林数

一、定义

\(~~~~\) 定义其为把 \(n\)区分的球放入 \(r\)互不区分的盒子里,且不空盒的方案数为第二类斯特林数。记作 \(S(n,r)\) ,也可以记作 \(\begin{Bmatrix} n\\r \end{Bmatrix}\)

二、计算

\(~~~~\) 1、递推

\(~~~~\) 我们考虑如何用之前的状态来推出当前的 \(S(n,r)\)

\(~~~~\) 不难想到,式子应该是:

\[S(n,r)=r\times S(n-1,r)+S(n-1,r-1),\ \ \ \ n\geq r\geq 1 \]

\(~~~~\) 加号前面表示新放一个球,可以放到已有的 \(r\) 个盒子中的任意一个。加号后面表示新放一个球,同时新开一个盒子,由于不空盒,且前面并没有限制来保证空盒的问题,因此必须在这里保证新开的盒子不空,故只能放入新盒子。

\(~~~~\) 时间复杂度 \(\mathcal{O(nr)}\)

查看代码
void Pre(int k)
{
	S[0][1]=1;//注意初始条件
	for(int i=1;i<=k;i++)
	{
		for(int j=1;j<=i;j++) S[i][j]=S[i-1][j]*j+S[i-1][j-1];//i球,j盒 
	} 
}

\(~~~~\) 2、容斥

\(~~~~\) 先给式子,再来解释:

\[S(n,k)=\dfrac{1}{k!}\sum_{i=0}^k (-1)^i \begin{pmatrix} k\\i \end{pmatrix} (k-i)^n \]

\(~~~~\) 首先把 \(\dfrac{1}{k!}\) 移到等号左边,此时 \(S(n,k)\times k!\) 相当于让盒子互相区分的方案数。

\(~~~~\) 右边我们用 \(i\) 枚举至少空盒数量(恰好是很难计算的),因此容斥,再选出保证为空的盒子集合,此时 \(n\) 个球每个都有 \(k-i\) 个盒子可以选择,故乘上 \((k-i)^n\)

\(~~~~\) 时间复杂度 \(\mathcal{O(k)}\)

三、性质

\(~~~~\) 1、前置知识?

\(~~~~\) 定义下降幂: \(x^{\underline n}=\dfrac{x!}{(x-n)!}\) ,读作 \(x\)\(n\) 次下降幂。你说这个东西看起来很陌生?其实它就是排列数 \(A_x^n\) 。具体来说也就是 \(x\) 向下乘 \(n\) 位。

\(~~~~\) 所以这根本就不算前置知识(bushi

\(~~~~\) 2、第二类斯特林数的性质

\(~~~~ ~~~~\) 2.1

\[\large x^n=\sum_{k=0}^n \begin{Bmatrix} n\\k \end{Bmatrix} x^{\underline k} \]

\(~~~~ ~~~~\) 从组合意义来解释:左边表示将 \(n\) 个球放入 \(x\) 个互相区分的盒子中,盒子可空的方案数。

\(~~~~ ~~~~\) 右边则用 \(k\) 来枚举非空的盒子个数,用 \(\begin{Bmatrix} n\\k \end{Bmatrix}\) 来计算方案。需要由于盒子互相区分,而前面的第二类斯特林数没有区分,因此有 \(A_x^k\) 的选盒子方案数,把排列数换成下降幂即可。

\(~~~~ ~~~~\) 2.2

\[\begin{pmatrix} n\\i \end{pmatrix} i^{\underline j}=\begin{pmatrix} n-j\\i-j \end{pmatrix}n^{\underline j} \]

\(~~~~ ~~~~\) 证明的话把组合数和下降幂都展开,易证。

\(~~~~ ~~~~\) 而这个性质可以在左边不方便算的时候变为右边,\(n^{\underline j}\)\(i\) 无关,可以提前。

\(~~~~ ~~~~\) 关键是要熟悉式子的形式。

四、例题 CF1278F Cards

\(~~~~\) 题意:有 \(n\) 个互相独立的随机变量 \(x_i\),每个都有 \(\frac{1}{m}\) 的概率为 \(1\),剩下概率取 \(0\)。求:

\[E((\sum\limits_{i=1}^n x_i)^k) \]

\(~~~~\) 即求出现 \(1\) 的次数的 \(k\) 次方的期望。

\(~~~~\) \(1\leq n,m<998244353,1\leq k\leq 5000\)

\(~~~~\) 题解:

\(~~~~\) \(k\) 次方的期望不等于期望的 \(k\) 次方。\(k\) 次方的期望不等于期望的 \(k\) 次方。\(k\) 次方的期望不等于期望的 \(k\) 次方。

\(~~~~\)\(p=\frac{1}m\)

\(~~~~\) 用 概率 \(\times\) 权值, 注意枚举哪些变量为 \(1\) ,很容易推出答案式子:

\[\sum_{i=1}^n \begin{pmatrix} n \\ i\end{pmatrix}\times p^i\times (1-p)^{n-i}\times i^k \]

\(~~~~\) 但这没法算,必须化简。用 2.1 展开 \(i^k\)

\[\sum_{i=1}^n \begin{pmatrix} n \\ i\end{pmatrix}\times p^i\times (1-p)^{n-i}\times \sum_{j=0}^k \begin{Bmatrix} k\\j \end{Bmatrix}i^{\underline j} \]

\(~~~~\) 提前枚举 \(j\)\(i^{\underline j}\) 甩到后面,方便利用 2.2

\[\sum_{j=0}^k \begin{Bmatrix} k\\j \end{Bmatrix}i^{\underline j} \times \sum_{i=1}^n \begin{pmatrix} n \\ i\end{pmatrix}\times p^i\times (1-p)^{n-i}\\ \sum_{j=0}^k \begin{Bmatrix} k\\j \end{Bmatrix} \times \sum_{i=1}^n \begin{pmatrix} n \\ i\end{pmatrix}\times p^i\times (1-p)^{n-i}\times i^{\underline j} \\ \sum_{j=0}^k \begin{Bmatrix} k\\j \end{Bmatrix}\times \sum_{i=1}^n p^i\times (1-p)^{n-i}\times \begin{pmatrix} n-j\\i-j \end{pmatrix}n^{\underline j} \]

\(~~~~\) \(n^{\underline j}\) 丢到前面,前面都是可以算的考虑后面怎么处理。

\(~~~~\) \(p^n\)\((1-p)^{n-i}\) 的指数和都是 \(n\) ,且底数和为 \(1\) ,可以往二项式定理考虑,但后面的组合数不对。

\(~~~~\) 因此改枚举 \(i\) 为枚举 \(i-j\) ,使得 \(\sum\) 的上限与组合数的底一致, 则式子变为:

\[\sum_{j=0}^k n^{\underline j}\begin{Bmatrix} k\\j \end{Bmatrix}\times \sum_{i=1}^{n-j} p^{i+j}\times (1-p)^{n-i-j}\times \begin{pmatrix} n-j\\i \end{pmatrix} \\ \sum_{j=0}^k n^{\underline j}\begin{Bmatrix} k\\j \end{Bmatrix}\times p^j\times \sum_{i=1}^{n-j} p^i\times (1-p)^{n-i-j}\times \begin{pmatrix} n-j\\i \end{pmatrix} \]

\(~~~~\) 把后面部分用二项式定理逆向回去:

\[\sum_{j=0}^k n^{\underline j} \begin{Bmatrix} k\\j \end{Bmatrix}\times p^i\times [p+(1-p)]^{n-j} \]

\(~~~~\) 因此最后的答案为:

\[\sum_{j=0}^k n^{\underline j} \begin{Bmatrix} k\\j \end{Bmatrix}\times p^i \]

\(~~~~\) 时间复杂度 \(\mathcal{O(k^2)}\)

查看代码
const ll MOD=998244353;
ll Mul(ll a,ll b){return a*b%MOD;}
ll Add(ll a,ll b){return ((a+b)%MOD+MOD)%MOD;}
void Pre()
{
	Fac[0]=Fac2[0]=1;for(int i=1;i<=k;i++) Fac[i]=Mul(Fac[i-1],i),Fac2[i]=Mul(Fac2[i-1],n-i+1);
	S[0][1]=1;
	for(int i=1;i<=k;i++)
	{
		for(int j=1;j<=i;j++) S[i][j]=Add(Mul(S[i-1][j],j),S[i-1][j-1]);
	} 
}
int main() {
	scanf("%lld %lld %lld",&n,&m,&k);
	Pre();
	ll Ans=0,P=qpow(m,MOD-2);
	for(int i=0;i<=k;i++) 
		Ans=Add(Ans,Mul(S[k][i],Mul(Fac2[i],qpow(P,i))));
	printf("%lld",Ans); 
	return 0;
}
原文地址:https://www.cnblogs.com/Azazel/p/14602097.html