第一类斯特林数
有 n n n 个不同的小球,将它们串成 m m m 条项链,有多少种不同的方案?
第一类斯特林数的表示方法为
[
n
m
]
\left[\begin{matrix}n\\m\end{matrix}\right]
[nm] 或
s
(
n
,
m
)
s(n,m)
s(n,m),表示
n
n
n 个不同的小球串成
m
m
m 条项链的方案数,考虑第
n
n
n 个小球的位置,要么接在前面
n
−
1
n-1
n−1 个小球中的某一个的后面,要么就新开一条项链,那么递推式为:
s
(
n
,
m
)
=
(
n
−
1
)
s
(
n
−
1
,
m
)
+
s
(
n
−
1
,
m
−
1
)
s(n,m)=(n-1)s(n-1,m)+s(n-1,m-1)
s(n,m)=(n−1)s(n−1,m)+s(n−1,m−1)
用递推式来求 s s s 的话时间复杂度为 O ( n m ) O(nm) O(nm),但是有时候我们不需要所有的 s ( i , j ) s(i,j) s(i,j),只需要一个特定位置的值,此时可以考虑用生成函数来优化。
转化一下上面的递推,第
i
i
i 次选择时,有
i
−
1
i-1
i−1 种选择不创造新的项链,有
1
1
1 种选择创造一条新的项链,写成生成函数就是:
∏
i
=
0
n
−
1
(
x
+
i
)
\prod_{i=0}^{n-1} (x+i)
i=0∏n−1(x+i)
此时可以用分治来解决,每一层再用 F F T FFT FFT 将左右两边的多项式乘起来。最后得到的多项式中, x m x^m xm 的系数就是 s ( n , m ) s(n,m) s(n,m),时间复杂度 O ( n log 2 n ) O(n\log^2n) O(nlog2n)。
但是有些题会卡这种做法,因为存在更优秀的 O ( n log n ) O(n\log n) O(nlogn) 做法。
具体参考这题。
第二类斯特林数
有 n n n 个不同的小球,放在 m m m 个相同的盒子里,每个盒子都不能为空,问有多少种方案。
这东西和上面不一样的地方就是:在同一个盒子内,不在乎小球的顺序;而上面的项链在乎。
第二类斯特林数的表示方法为 { n m } \left\{\begin{matrix}n\\m\end{matrix}\right\} {nm} 或 S ( n , m ) S(n,m) S(n,m),类似的,表示 n n n 个不同的小球放在 m m m 个相同的盒子里的方案数。(注意,第一类是小 s s s,第二类是大 S S S)。
考虑第
n
n
n 个小球,要么跟前面的小球放同一个盒子里,要么自己新开一个盒子:
S
(
n
,
m
)
=
m
S
(
n
−
1
,
m
)
+
S
(
n
−
1
,
m
−
1
)
S(n,m)=mS(n-1,m)+S(n-1,m-1)
S(n,m)=mS(n−1,m)+S(n−1,m−1)
此时 S ( n − 1 , m ) S(n-1,m) S(n−1,m) 的系数为 m m m,不能使用生成函数来加速了,但是可以考虑容斥。
为了方便,先假设每个盒子都不一样,最后的方案数再除以 m ! m! m! 即可。
容斥的话就要考虑不合法的方案,在这里,有盒子空了就是不合法,那么显然能得到:
S
(
n
,
m
)
=
1
m
!
∑
i
=
0
m
(
−
1
)
i
C
m
i
(
m
−
i
)
n
S(n,m)=\frac1 {m!}\sum_{i=0}^m (-1)^i C_m^i (m-i)^n
S(n,m)=m!1i=0∑m(−1)iCmi(m−i)n
其中, i i i 表示至少有 i i i 个盒子为空的方案数, ( − 1 ) i (-1)^i (−1)i 是容斥系数, C m i C_m^i Cmi 表示从 m m m 个盒子里选出 i i i 个作为空盒子(因为我们假设了盒子都不一样,所以需要用组合数),然后 n n n 个球放在剩下的 m − i m-i m−i 个盒子里的方案数就是 ( m − i ) n (m-i)^n (m−i)n,以及最前面乘的 1 m ! \frac 1 {m!} m!1 就是上面所提到的。
推一下:
1
m
!
∑
i
=
0
m
(
−
1
)
i
m
!
i
!
(
m
−
i
)
!
(
m
−
i
)
n
=
∑
i
=
0
m
(
−
1
)
i
i
!
×
(
m
−
i
)
n
(
m
−
i
)
!
\begin{aligned} &~~~~\frac 1 {m!}\sum_{i=0}^m (-1)^i\frac {m!} {i!(m-i)!}(m-i)^n\\ &=\sum_{i=0}^m\frac {(-1)^i} {i!}\times \frac {(m-i)^n} {(m-i)!} \end{aligned}
m!1i=0∑m(−1)ii!(m−i)!m!(m−i)n=i=0∑mi!(−1)i×(m−i)!(m−i)n
于是发现这个东西可以用 F F T FFT FFT 搞一搞,时间复杂度为 O ( n log n ) O(n\log n) O(nlogn)。
斯特林数与下降幂
斯特林数和下降幂可谓是息息相关,这里就简单讲一下利用斯特林数如何做普通多项式与下降幂多项式的转化。
一般幂转下降幂
对于
x
n
x^n
xn,有一个经典套路,考虑其组合意义,
n
n
n 个不同的球放
x
x
x 个不同的盒子里的方案数,枚举一下有多少个非空的盒子:
x
n
=
∑
i
=
1
x
(
x
i
)
S
(
n
,
i
)
i
!
=
∑
i
=
1
x
S
(
n
,
i
)
x
i
‾
x^n=\sum_{i=1}^x \binom x i S(n,i) i!=\sum_{i=1}^x S(n,i)x^{\underline i}
xn=i=1∑x(ix)S(n,i)i!=i=1∑xS(n,i)xi
一般见到的里面求和的上下界其实是 0 0 0 ~ n n n,事实上不难发现这个更宽松的上下界多出来的部分全都是 0 0 0,但是有时候推式子写这个上下界推的会更舒服。
下降幂转一般幂
上面提到了,第一类斯特林数的生成函数就是个上升幂,即:
∑
i
=
1
n
s
(
n
,
i
)
x
i
=
∏
i
=
0
n
−
1
(
x
+
i
)
=
x
n
‾
\sum_{i=1}^n s(n,i)x^i=\prod_{i=0}^{n-1} (x+i)=x^{\overline n}
i=1∑ns(n,i)xi=i=0∏n−1(x+i)=xn
假如我们将每一个
(
x
+
i
)
(x+i)
(x+i) 替换成
(
x
−
i
)
(x-i)
(x−i),那么求出来的就是下降幂了。此时左边多项式系数只需要乘以
(
−
1
)
n
−
i
(-1)^{n-i}
(−1)n−i,等式就依然成立,即:
x
n
‾
=
∑
i
=
1
n
(
−
1
)
n
−
i
s
(
n
,
i
)
x
i
x^{\underline n}=\sum_{i=1}^n (-1)^{n-i} s(n,i)x^i
xn=i=1∑n(−1)n−is(n,i)xi
贝尔数
有 n n n 个不同的小球放在若干个相同的盒子里,问有多少种不同的方案。
显然就是第二类斯特林数的和,即 B n = ∑ i = 1 n S ( n , k ) B_n=\sum_{i=1}^n S(n,k) Bn=∑i=1nS(n,k)。
同时,也能得到递推公式: B n + 1 = ∑ i = 0 n C n i B i B_{n+1}=\sum_{i=0}^nC_n^i B_i Bn+1=∑i=0nCniBi,枚举的 i i i 表示有 n − i n-i n−i 个球和第 n + 1 n+1 n+1 个球在同一个盒子里,那么剩下的 i i i 个就不在同一个盒子里,他们的方案数就是 B i B_i Bi,然后由于球是不一样的,所以还要乘上 C n i C_n^i Cni 即从 n n n 个球里选 i i i 个球的方案数。
考虑如何快速求出一个
B
n
B_n
Bn,将
B
n
=
∑
i
=
1
n
S
(
n
,
k
)
B_n=\sum_{i=1}^nS(n,k)
Bn=∑i=1nS(n,k) 展开,得到
B
n
=
∑
i
=
1
n
∑
j
=
0
i
(
−
1
)
j
j
!
×
(
n
−
i
)
n
(
n
−
i
)
!
=
∑
j
=
0
n
(
−
1
)
j
j
!
∑
i
=
j
n
(
n
−
i
)
n
(
n
−
i
)
!
\begin{aligned} B_n&=\sum_{i=1}^n\sum_{j=0}^i \frac {(-1)^j} {j!}\times \frac {(n-i)^n} {(n-i)!}\\ &=\sum_{j=0}^n \frac {(-1)^j} {j!}\sum_{i=j}^{n} \frac {(n-i)^n} {(n-i)!} \end{aligned}
Bn=i=1∑nj=0∑ij!(−1)j×(n−i)!(n−i)n=j=0∑nj!(−1)ji=j∑n(n−i)!(n−i)n
O ( n log n ) O(n\log n) O(nlogn) 预处理 ( n − i ) n ( n − i ) ! \frac {(n-i)^n} {(n-i)!} (n−i)!(n−i)n 的后缀和,就可以 O ( n ) O(n) O(n) 求出 B n B_n Bn 了。
题表
第一类斯特林数模板题:上面那题。