Stirling数学习笔记

第一类

在此仅讨论无符号第一类Stirling数。

定义

n个有标号的球组成m个圆排列的方案数,即第一类斯特林数,记做 S 1 ( n , m ) S_1(n,m) S1(n,m),亦记做 [ n m ] \begin{bmatrix}n\\ m\end{bmatrix} [nm]

递推式

考虑最后一个元素,可以新组成一个圆排列,也可以插入之前 n − 1 n-1 n1个元素的任意一个之后,不难得到其递推式为

S 1 ( n , m ) = S 1 ( n − 1 , m − 1 ) + ( n − 1 ) S 1 ( n − 1 , m ) S_1(n,m)=S_1(n-1,m-1)+(n-1)S_1(n-1,m) S1(n,m)=S1(n1,m1)+(n1)S1(n1,m)

更快速的求法

第n行的生成函数为
∏ i = 0 n − 1 ( x + i ) = x n ‾ \prod_{i=0}^{n-1}(x+i)=x^{\overline n} i=0n1(x+i)=xn

其中的第m项系数即为 S 1 ( n , m ) S_1(n,m) S1(n,m)

为啥呢?我们不妨从递推式进行思考,第n-1行到第n行,如果列数不增加,则要乘以当前的行数,如果列数增加1,就以1倍加入。

那么我们用分治FFT就可以在 O ( n log ⁡ 2 n ) O(n\log^2 n) O(nlog2n)的复杂度求出某一行的值了。


然而其实还有更优秀的方法——倍增。

f ( x ) = x n ‾ , g ( x ) = ( x + n ) n ‾ = f ( x + n ) f(x)=x^{\overline n},g(x)=(x+n)^{\overline n}=f(x+n) f(x)=xn,g(x)=(x+n)n=f(x+n),则有 f ( x ) g ( x ) = x 2 n ‾ f(x)g(x)=x^{\overline{2n}} f(x)g(x)=x2n

那么考虑倍增,我们希望能通过 f ( x ) f(x) f(x),快速的求出 g ( x ) g(x) g(x)

不妨设
f ( x ) = ∑ i = 0 n a i x i f(x)=\sum_{i=0}^n a_i x^i f(x)=i=0naixi

g ( x ) = ∑ i = 0 n a i ( x + n ) i = ∑ i = 0 n a i ∑ j = 0 i ( i j ) n i − j x j g(x)=\sum_{i=0}^n a_i (x+n)^i=\sum_{i=0}^na_i\sum_{j=0}^i\binom i j n^{i-j}x^j g(x)=i=0nai(x+n)i=i=0naij=0i(ji)nijxj
改变求和顺序
g ( x ) = ∑ i = 0 n ( ∑ j = i n ( j i ) n j − i a j ) x i g(x)=\sum_{i=0}^n\biggl(\sum_{j=i}^n \binom j i n^{j-i} a_j\biggr) x^i g(x)=i=0n(j=in(ij)njiaj)xi

把组合数一拆,卷积即可

时间复杂度为 T ( n ) = T ( n 2 ) + O ( n log ⁡ n ) = O ( n log ⁡ n ) T(n)=T(\frac n 2)+O(n\log n)=O(n\log n) T(n)=T(2n)+O(nlogn)=O(nlogn),常数略大,但相比分治FFT有较大优势。

第二类

定义

n个有标号球放入m个无标号箱子,且每个箱子不为空的方案数,记做 S 2 ( n , m ) S_2(n,m) S2(n,m),亦记做 \{ n m \} n\brace m {mn}

公式

同样的,我们思考一下最后一个球新做一个箱子还是放入之前的箱子中去,不难得到:

S 2 ( n , m ) = S 2 ( n − 1 , m − 1 ) + m S 2 ( n − 1 , m ) S_2(n,m)=S_2(n-1,m-1)+mS_2(n-1,m) S2(n,m)=S2(n1,m1)+mS2(n1,m)


我们也可以用容斥来做

至少有 i i i个箱子为空的方案数
( m i ) ( m − i ) n \binom m i (m-i)^n (im)(mi)n
容斥一下,再把箱子改为无标号的即得
S 2 ( n , m ) = 1 m ! ∑ i = 0 m ( − 1 ) i ( m i ) ( m − i ) n S_2(n,m)=\frac 1 {m!}\sum_{i=0}^m (-1)^i \binom m i (m-i)^n S2(n,m)=m!1i=0m(1)i(im)(mi)n
把组合数拆开同样可以发现就是一个卷积,求一行的复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn)

斯特林反演

g ( n ) = ∑ i = 0 n \{ n i \} f ( i ) g(n)=\sum_{i=0}^n {n \brace i}f(i) g(n)=i=0n{in}f(i)

f ( n ) = ∑ i = 0 n ( − 1 ) n − i [ n i ] g ( i ) f(n)=\sum_{i=0}^n (-1)^{n-i} \begin{bmatrix}n\\ i\end{bmatrix} g(i) f(n)=i=0n(1)ni[ni]g(i)

可能要用到下面这么两个公式,具体的证明嘛,我也没证出来。。

∑ i = 1 n ( − 1 ) n − i \{ n i \} [ i m ] = [ m = n ] \sum_{i=1}^n (-1)^{n-i} {n \brace i}\begin{bmatrix}i\\ m\end{bmatrix}=[m=n] i=1n(1)ni{in}[im]=[m=n]

∑ i = 1 n ( − 1 ) n − i [ n i ] \{ i m \} = [ m = n ] \sum_{i=1}^n (-1)^{n-i} \begin{bmatrix}n\\ i\end{bmatrix}{i \brace m}=[m=n] i=1n(1)ni[ni]{mi}=[m=n]

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值