第一类
在此仅讨论无符号第一类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 n−1个元素的任意一个之后,不难得到其递推式为
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(n−1,m−1)+(n−1)S1(n−1,m)
更快速的求法
第n行的生成函数为
∏
i
=
0
n
−
1
(
x
+
i
)
=
x
n
‾
\prod_{i=0}^{n-1}(x+i)=x^{\overline n}
i=0∏n−1(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=0∑naixi
则
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=0∑nai(x+n)i=i=0∑naij=0∑i(ji)ni−jxj
改变求和顺序
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=0∑n(j=i∑n(ij)nj−iaj)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(n−1,m−1)+mS2(n−1,m)
我们也可以用容斥来做
至少有
i
i
i个箱子为空的方案数
(
m
i
)
(
m
−
i
)
n
\binom m i (m-i)^n
(im)(m−i)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=0∑m(−1)i(im)(m−i)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=0∑n{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=0∑n(−1)n−i[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=1∑n(−1)n−i{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=1∑n(−1)n−i[ni]{mi}=[m=n]