概念
- 斯特林数(Stirling number)是由18世纪数学家James Stirling提出的两类数。
- 第一类:轮换数,将n个数排成k个非空的环(圆排列,有序)的方案数,用 s ( n , m ) s(n,m) s(n,m)或 [ n k ] \left[ \begin{matrix}n\\k\end{matrix} \right] [nk]表示。还分为无符号第一类斯特林数 s u ( n , m ) s_u(n,m) su(n,m)和带符号第一类斯特林数 s s ( n , m ) s_s(n,m) ss(n,m)。
- 第二类:子集数,将n个数排成k个非空集合(集合内无序)的方案数,用 S ( n , m ) S(n,m) S(n,m)或 { n k } \left\{ \begin{matrix}n\\k\end{matrix} \right\} {nk}表示。
第一类斯特林数
边界条件&&递推式
- 先考虑无符号第一类斯特林数 s u ( n , m ) s_u(n,m) su(n,m)。
- 根据定义,易得边界条件:
s ( n , k ) = { 0 n < k 1 n = k 0 n > 0 ∧ k = 0 s(n,k)=\begin{cases}0 & n<k \\ 1 & n=k \\ 0 & n>0\ ∧\ k=0 \end{cases} s(n,k)=⎩⎪⎨⎪⎧010n<kn=kn>0 ∧ k=0 - 假设现在已知 s ( n − 1 , k − 1 ) s(n-1,k-1) s(n−1,k−1),我们要加入一个新数 n n n。它可以考虑自己形成一个新的环,或者插入任意一个已有的数后面,因此: [ n k ] = [ n − 1 k − 1 ] + ( n − 1 ) [ n − 1 k ] \left[ \begin{matrix}n\\k\end{matrix} \right]=\left[ \begin{matrix}n-1\\k-1\end{matrix} \right]+(n-1)\left[ \begin{matrix}n-1\\k\end{matrix} \right] [nk]=[n−1k−1]+(n−1)[n−1k]
- 有符号的第一类斯特林数 s s ( n , k ) s_s(n,k) ss(n,k)与此类似。其递推式为: s s ( n , k ) = ( − 1 ) n + k s u ( n , k ) = s s ( n − 1 , k − 1 ) − ( n − 1 ) × s s ( n − 1 , k ) s_s(n,k)=(-1)^{n+k}s_u(n,k)=s_s(n-1,k-1)-(n-1)\times s_s(n-1,k) ss(n,k)=(−1)n+ksu(n,k)=ss(n−1,k−1)−(n−1)×ss(n−1,k)
- 时间&空间复杂度: O ( n 2 ) O(n^2) O(n2)。
与上升/下降幂的关系
- 第一类斯特林数与上升幂
x
n
‾
=
x
(
x
+
1
)
(
x
+
2
)
⋯
(
x
+
n
−
1
)
x^{\overline{n}}=x(x+1)(x+2)\cdots(x+n-1)
xn=x(x+1)(x+2)⋯(x+n−1)满足如下所示的关系:
x n ‾ = ∑ k = 1 n s u ( n , k ) × x k x^{\overline{n}}=\sum_{k=1}^n s_u(n,k)\times x^k xn=k=1∑nsu(n,k)×xk - 亦即第一类斯特林数表现为 x n ‾ x^{\overline{n}} xn的展开形式的各项系数。
- 该式子可利用 s u ( n , m ) s_u(n,m) su(n,m)的递推式通过数学归纳法来证明。但其亦有简单的组合意义:
- n n n个点,构成若干个环,要求一个环中所有点颜色相同,不同环不作要求。那么我们可以枚举环的组成( ∑ k = 1 n s u ( n , k ) \sum_{k=1}^n s_u(n,k) ∑k=1nsu(n,k)),再给每个环分配颜色( x k x^k xk);从另一个角度想,我们按编号从小到大加入每个点,每个点可在x种颜色中选择一种并自己形成一个新的环,亦可在前 n − 1 n-1 n−1个点中选择一个点接在它后面并继承它的颜色,那么操作方案数即为 x n ‾ x^{\overline{n}} xn。
- 上式加以变形可得到与下降幂
x
n
‾
=
x
(
x
−
1
)
(
x
−
2
)
⋯
(
x
−
n
+
1
)
x^{\underline{n}}=x(x-1)(x-2)\cdots(x-n+1)
xn=x(x−1)(x−2)⋯(x−n+1)的关系:
x n ‾ = ∑ k = 1 n ( − 1 ) n − k × s u ( n , k ) × x k = ∑ k = 1 n s s ( n , k ) × x k x^{\underline{n}}=\sum_{k=1}^n (-1)^{n-k}\times s_u(n,k)\times x^k=\sum_{k=1}^n s_s(n,k)\times x^k xn=k=1∑n(−1)n−k×su(n,k)×xk=k=1∑nss(n,k)×xk - 这是因为我们把 x n ‾ x^{\underline{n}} xn展开后,会发现它的各项系数的绝对值与 x n ‾ x^{\overline{n}} xn一致,只是正负性会交错排列。
较为快速的求法
- 考虑多项式 F ( x ) = ∏ i = 0 n − 1 ( x + i ) F(x)=\prod_{i=0}^{n-1}(x+i) F(x)=∏i=0n−1(x+i)的系数。
- F ( x ) = x n ‾ = ∑ k = 1 n [ k n ] x k = ∑ k = 0 n [ k n ] x k F(x)=x^{\overline{n}}=\sum_{k=1}^n\left[ ^n_k \right]x^k=\sum_{k=0}^n\left[ ^n_k \right]x^k F(x)=xn=∑k=1n[kn]xk=∑k=0n[kn]xk
- 因此, F ( x ) F(x) F(x)的k次项系数即为 [ k n ] \left[^n_k\right] [kn]。
- 考虑快速地求解 [ k n ] \left[^n_k\right] [kn]。
- 当有模数的时候,可以分治NTT求解 F ( x ) F(x) F(x)的各项系数(可以忽略掉 i = 0 i=0 i=0时的 ( x + i ) (x+i) (x+i))。我们进行CDQ分治,区间 [ 2 l − 1 , 2 r ] [2l-1,2r] [2l−1,2r]表示 ( x + l ) ( x + l + 1 ) ( x + l + 2 ) ⋯ ( x + r ) (x+l)(x+l+1)(x+l+2)\cdots(x+r) (x+l)(x+l+1)(x+l+2)⋯(x+r)的各项系数。记 m = l + r 2 m=\dfrac{l+r}2 m=2l+r,每次先求解区间 [ 2 l − 1 , 2 m ] [2l-1,2m] [2l−1,2m]和区间 [ 2 m + 1 , 2 r ] [2m+1,2r] [2m+1,2r],尔后再合并。
- 时间复杂度: O ( n log 2 2 n ) O(n\log_2^2n) O(nlog22n);空间复杂度: O ( n ) O(n) O(n)。
第二类斯特林数
回顾一下定义
- 第二类斯特林数:子集数,将n个数排成k个非空集合(集合内无序)的方案数,用 S ( n , m ) S(n,m) S(n,m)或 { n k } \left\{ \begin{matrix}n\\k\end{matrix} \right\} {nk}表示。
边界条件&&递推式
- 随便思考一下即可发现,边界条件与第一类斯特林数一致:
S ( n , k ) = { 0 n < k 1 n = k 0 n > 0 ∧ k = 0 S(n,k)=\begin{cases}0 & n<k \\ 1 & n=k \\ 0 & n>0\ ∧\ k=0 \end{cases} S(n,k)=⎩⎪⎨⎪⎧010n<kn=kn>0 ∧ k=0 - 假设现在已知 S ( n − 1 , k − 1 ) S(n-1,k-1) S(n−1,k−1),要加入新数 n n n。它可以自己形成一个新的集合,或者加进先前已有的任意一个集合中去,于是: { n k } = { n − 1 k − 1 } + k { n − 1 k } \left\{ \begin{matrix}n\\k\end{matrix} \right\}=\left\{ \begin{matrix}n-1\\k-1\end{matrix} \right\}+k\left\{ \begin{matrix}n-1\\k\end{matrix} \right\} {nk}={n−1k−1}+k{n−1k}
- 时间&空间复杂度: O ( n 2 ) O(n^2) O(n2)。
与下降幂的关系
- 第二类斯特林数与下降幂
x
k
‾
x^{\underline{k}}
xk满足如下所示的关系:
x n = ∑ k = 0 n S ( n , k ) × x k ‾ x^n = \sum_{k=0}^{n} S(n,k)\times x^{\underline{k}} xn=k=0∑nS(n,k)×xk - 与前面的一样,这个式子可以用数学归纳法证明,亦有组合意义:
- 假设我们用 x x x种颜色为 n n n个点染色,方案数显然是 x n x^n xn;而我们也可以枚举同种颜色的集合是什么( ∑ k = 0 n S ( n , k ) \sum_{k=0}^{n} S(n,k) ∑k=0nS(n,k)),然后从x种颜色中选出不同的颜色赋给这些集合( x k ‾ x^{\underline{k}} xk)。
通项公式
- 转换模型。不难发现 S ( n , k ) S(n,k) S(n,k)等价于:将 n n n个不同的球放入 m m m个无差别的盒子中,要求盒子非空的方案数。
- 我们先考虑盒子有差别的情况。
- 考虑容斥。枚举空盒数 i i i,在 m m m个盒子中选 i i i个即为 ( m i ) \binom mi (im);那么, n n n个球可以放进剩下的 m − i m-i m−i个盒子中,即为 ( m − i ) n (m-i)^n (m−i)n。容斥系数显然为 ( − 1 ) i (-1)^i (−1)i。(当然,严谨证明还是得推式子)
- 最后,消除盒子的差别,整体乘上一个 1 m ! \frac1{m!} m!1。
- 以上说明过于感性,下面我们来理性一下。
- 我们之前已经得出了: m n = ∑ i = 0 n { i n } m i ‾ m^n=\sum_{i=0}^n \left\{ ^n_i\right\}m^{\underline{i}} mn=∑i=0n{in}mi
- 把 m i ‾ m^{\underline{i}} mi拆开来就变成: ∑ i = 0 n ( m i ) { i n } i ! \sum_{i=0}^n \binom mi\left\{^n_i\right\}i! ∑i=0n(im){in}i!
- 那么,根据二项式反演,上式等价于: { m n } m ! = ∑ i = 0 m ( − 1 ) i ( m i ) ( m − i ) n \left\{^n_m\right\}m!=\sum_{i=0}^m(-1)^i\binom mi (m-i)^n {mn}m!=∑i=0m(−1)i(im)(m−i)n
- 然后,我们把 m ! m! m!丢到右边去。
- 至此,我们得到了第二类斯特林数的通项公式:
{ n m } = 1 m ! ∑ i = 0 m ( − 1 ) i ( m i ) ( m − i ) n = ∑ i = 0 m ( − 1 ) i ( m − i ) n i ! ( m − i ) ! \begin{Bmatrix}n\\m\end{Bmatrix}=\frac 1 {m!}\sum_{i=0}^m(-1)^i\binom mi(m-i)^n=\sum_{i=0}^m\frac{(-1)^i(m-i)^n}{i!(m-i)!} {nm}=m!1i=0∑m(−1)i(im)(m−i)n=i=0∑mi!(m−i)!(−1)i(m−i)n - 可以考虑预处理 1 i ! ( m − i ) ! \frac1{i!(m-i)!} i!(m−i)!1。单组询问的话,也可以预处理 ( m − i ) n (m-i)^n (m−i)n。
- 时间复杂度: O ( m log M ) O(m\log M) O(mlogM)或 O ( m ) O(m) O(m)。( M M M为模数)
- 如果我们要快速地求 S ( n , 0 ) ∼ S ( n , m ) S(n,0)\sim S(n,m) S(n,0)∼S(n,m)怎么破?我们发现通项公式中, ( − 1 ) i i ! \frac{(-1)^i}{i!} i!(−1)i只与 i i i有关, ( m − i ) n ( m − i ) ! \frac{(m-i)^n}{(m-i)!} (m−i)!(m−i)n只与 m − i m-i m−i有关。所以可设两个多项式,用一个FFT/NTT,即可在 O ( m log m ) O(m\log m) O(mlogm)的时间内求出。
与自然数幂和
- 第二类斯特林数的一大亮点是可以
龟快速求自然数幂和。 - 记
F
(
n
)
=
∑
i
=
1
n
i
k
F(n)=\sum_{i=1}^n i^k
F(n)=∑i=1nik。我们来现场推一波式子:
F ( n ) = ∑ i = 1 n ∑ j = 0 k { k j } i j ‾ = ∑ i = 1 n ∑ j = 0 k { k j } j ! ( i j ) = ∑ j = 0 k { k j } j ! ∑ i = j n ( i j ) \begin{aligned} F(n) & = \sum_{i=1}^{n} \sum_{j=0}^{k} \left\{ \begin{matrix}k\\j\end{matrix} \right\} i^{\underline{j}} \\ & = \sum_{i=1}^{n} \sum_{j=0}^{k} \left\{ \begin{matrix}k\\j\end{matrix} \right\} j!\left( \begin{matrix}i\\j\end{matrix}\right) \\ & = \sum_{j=0}^{k} \left\{ \begin{matrix}k\\j\end{matrix} \right\} j! \sum_{i=j}^n \left( \begin{matrix}i\\j\end{matrix}\right) \end{aligned} F(n)=i=1∑nj=0∑k{kj}ij=i=1∑nj=0∑k{kj}j!(ij)=j=0∑k{kj}j!i=j∑n(ij) - 现在已经可以 O ( n k ) O(nk) O(nk)求解了。但是我们想更快。
- 先给出一个结论: ∑ i = j n ( j i ) = ( j + 1 n + 1 ) \sum_{i=j}^n\left( ^i_j\right)=\left(^{n+1}_{j+1} \right) ∑i=jn(ji)=(j+1n+1)。
- 这个东西的证明,可以根据组合数的递推式依次展开
(
j
+
1
n
+
1
)
\left(^{n+1}_{j+1} \right)
(j+1n+1)来得到:
( n + 1 j + 1 ) = ( n j ) + ( n j + 1 ) = ( n j ) + ( n − 1 j ) + ( n − 1 j + 1 ) = ( n j ) + ( n − 1 j ) + ( n − 2 j ) + ( n − 2 j + 1 ) = ( n j ) + ( n − 1 j ) + ⋯ + ( j j ) + ( j j + 1 ) = ( n j ) + ( n − 1 j ) + ⋯ + ( j j ) \begin{aligned} \left( \begin{matrix}n+1\\j+1\end{matrix}\right) & =\left( \begin{matrix}n\\j\end{matrix}\right) + \left( \begin{matrix}n\\j+1\end{matrix}\right) \\& =\left( \begin{matrix}n\\j\end{matrix}\right) + \left( \begin{matrix}n-1\\j\end{matrix}\right) + \left( \begin{matrix}n-1\\j+1\end{matrix}\right) \\& =\left( \begin{matrix}n\\j\end{matrix}\right) + \left( \begin{matrix}n-1\\j\end{matrix}\right) + \left( \begin{matrix}n-2\\j\end{matrix}\right) + \left( \begin{matrix}n-2\\j+1\end{matrix}\right) \\& =\left( \begin{matrix}n\\j\end{matrix}\right) + \left( \begin{matrix}n-1\\j\end{matrix}\right) + \cdots + \left( \begin{matrix}j\\j\end{matrix}\right) + \left( \begin{matrix}j\\j+1\end{matrix}\right)\\& =\left( \begin{matrix}n\\j\end{matrix}\right) + \left( \begin{matrix}n-1\\j\end{matrix}\right) + \cdots + \left( \begin{matrix}j\\j\end{matrix}\right) \end{aligned} (n+1j+1)=(nj)+(nj+1)=(nj)+(n−1j)+(n−1j+1)=(nj)+(n−1j)+(n−2j)+(n−2j+1)=(nj)+(n−1j)+⋯+(jj)+(jj+1)=(nj)+(n−1j)+⋯+(jj) - 也可以考虑组合意义: n + 1 n+1 n+1个数排成一排,选 j + 1 j+1 j+1个,枚举第一个数选的位置,剩下的数再选 j j j个,于是就成了上面的式子。
- 然后我们可以继续化简。
- 接着上面的队形:
F ( n ) = ∑ j = 0 k { k j } j ! ∑ i = j n ( i j ) = ∑ j = 0 k { k j } j ! ( n + 1 j + 1 ) = ∑ j = 0 k { k j } ( n + 1 ) j + 1 ‾ j + 1 \begin{aligned} F(n) & = \sum_{j=0}^{k} \left\{ \begin{matrix}k\\j\end{matrix} \right\} j! \sum_{i=j}^n \left( \begin{matrix}i\\j\end{matrix}\right) \\& = \sum_{j=0}^{k} \left\{ \begin{matrix}k\\j\end{matrix} \right\} j!\left( \begin{matrix}n+1\\j+1\end{matrix}\right)\\& = \sum_{j=0}^k\left\{\begin{matrix}{k}\\{j}\end{matrix}\right\} \frac{(n+1)^{\underline {j+1}}}{j+1} \end{aligned} F(n)=j=0∑k{kj}j!i=j∑n(ij)=j=0∑k{kj}j!(n+1j+1)=j=0∑k{kj}j+1(n+1)j+1 - { j k } \left\{ ^k_j\right\} {jk}的值可以 O ( k 2 ) O(k^2) O(k2)或 O ( k log k ) O(k\log k) O(klogk)预处理。而 ( n + 1 ) j + 1 ‾ (n+1)^{\underline{j+1}} (n+1)j+1是连续的 j + 1 j+1 j+1个自然数的乘积,则其一定是 j + 1 j+1 j+1的倍数,因此不必逆元。(当然,假如 ( n + 1 ) (n+1) (n+1)太大,要先模,那就得逆元了)逆元可以 O ( k ) O(k) O(k)预处理,因此单次询问复杂度为 O ( k ) O(k) O(k)。
两类斯特林数之间的关系
∑ i = 0 n S ( n , i ) s ( i , m ) = ∑ i = 0 n s ( n , i ) S ( i , m ) \sum_{i=0}^nS(n,i)s(i,m)=\sum_{i=0}^ns(n,i)S(i,m) i=0∑nS(n,i)s(i,m)=i=0∑ns(n,i)S(i,m)
- 这是为什么呢?我觉得应该可以数学归纳法,在此不作证明。