第二类斯特林数
一、定义
\(~~~~\) 定义其为把 \(n\) 个区分的球放入 \(r\) 个互不区分的盒子里,且不空盒的方案数为第二类斯特林数。记作 \(S(n,r)\) ,也可以记作 \(\begin{Bmatrix} n\\r \end{Bmatrix}\) 。
二、计算
\(~~~~\) 1、递推
\(~~~~\) 我们考虑如何用之前的状态来推出当前的 \(S(n,r)\) 。
\(~~~~\) 不难想到,式子应该是:
\(~~~~\) 加号前面表示新放一个球,可以放到已有的 \(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、容斥
\(~~~~\) 先给式子,再来解释:
\(~~~~\) 首先把 \(\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
\(~~~~ ~~~~\) 从组合意义来解释:左边表示将 \(n\) 个球放入 \(x\) 个互相区分的盒子中,盒子可空的方案数。
\(~~~~ ~~~~\) 右边则用 \(k\) 来枚举非空的盒子个数,用 \(\begin{Bmatrix} n\\k \end{Bmatrix}\) 来计算方案。需要由于盒子互相区分,而前面的第二类斯特林数没有区分,因此有 \(A_x^k\) 的选盒子方案数,把排列数换成下降幂即可。
\(~~~~ ~~~~\) 2.2
\(~~~~ ~~~~\) 证明的话把组合数和下降幂都展开,易证。
\(~~~~ ~~~~\) 而这个性质可以在左边不方便算的时候变为右边,\(n^{\underline j}\) 与 \(i\) 无关,可以提前。
\(~~~~ ~~~~\) 关键是要熟悉式子的形式。
四、例题 CF1278F Cards
\(~~~~\) 题意:有 \(n\) 个互相独立的随机变量 \(x_i\),每个都有 \(\frac{1}{m}\) 的概率为 \(1\),剩下概率取 \(0\)。求:
\(~~~~\) 即求出现 \(1\) 的次数的 \(k\) 次方的期望。
\(~~~~\) \(1\leq n,m<998244353,1\leq k\leq 5000\)
\(~~~~\) 题解:
\(~~~~\) \(k\) 次方的期望不等于期望的 \(k\) 次方。\(k\) 次方的期望不等于期望的 \(k\) 次方。\(k\) 次方的期望不等于期望的 \(k\) 次方。
\(~~~~\) 记 \(p=\frac{1}m\) 。
\(~~~~\) 用 概率 \(\times\) 权值, 注意枚举哪些变量为 \(1\) ,很容易推出答案式子:
\(~~~~\) 但这没法算,必须化简。用 2.1
展开 \(i^k\) :
\(~~~~\) 提前枚举 \(j\) 把 \(i^{\underline j}\) 甩到后面,方便利用 2.2
:
\(~~~~\) \(n^{\underline j}\) 丢到前面,前面都是可以算的考虑后面怎么处理。
\(~~~~\) \(p^n\) 和 \((1-p)^{n-i}\) 的指数和都是 \(n\) ,且底数和为 \(1\) ,可以往二项式定理考虑,但后面的组合数不对。
\(~~~~\) 因此改枚举 \(i\) 为枚举 \(i-j\) ,使得 \(\sum\) 的上限与组合数的底一致, 则式子变为:
\(~~~~\) 把后面部分用二项式定理逆向回去:
\(~~~~\) 因此最后的答案为:
\(~~~~\) 时间复杂度 \(\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;
}