整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


真的特别简单,我尽量讲的详细一些,本文包含了几乎所有性质定理证明,老少皆宜 ~

内容过多,质量过硬,建议先赞后看 ~

我敲了两天了,点个赞呗呜呜呜

目录

  • 0x00 斯特林数概述
  • 0x10 第一类斯特林数
    • 0x11 第一类斯特林数的定义
    • 0x12 递推求第一类斯特林数(O(n2)\mathcal{O}(n^2)O(n2))
    • 0x13 第一类斯特林数表与斯特林三角
    • 0x14 第一类斯特林数的性质
    • 0x15 上升幂与下降幂
    • 0x16 第一类斯特林数的生成函数
    • 0x17 生成函数求第一类斯特林数(O(nlogn)\mathcal{O}(nlogn)O(nlogn))
    • 0x18 简单应用举例
    • 0x19 竞赛例题选讲
  • 0x20 第二类斯特林数
    • 0x21 第二类斯特林数的定义
    • 0x22 递推求第二类斯特林数(O(n2)\mathcal O(n^2)O(n2))
    • 0x23 第二类斯特林数表与斯特林三角
    • 0x24 第二类斯特林数的性质
    • 0x24 第二类斯特林数的生成函数
    • 0x25 第二类斯特林数的通项公式
    • 0x26 生成函数求第二类斯特林数(O(nlogn)\mathcal O(nlogn)O(nlogn))
    • 0x28 简单应用举例
    • 0x29 竞赛例题选讲
  • 0x30 第三类斯特林数
    • 0x31 第三类斯特林数(拉赫数)定义
    • 0x32 递推求第三类斯特林数
    • 0x33 第三类斯特林数表
    • 0x34 第三类斯特林数的性质
  • 0x40 三类斯特林数之间的转换
  • 0x50 斯特林反演
    • 0x51 前置知识
    • 0x52 斯特林反演及其证明
    • 0x53 竞赛例题选讲

0x00 斯特林数概述

  在数学中,斯特林数(Stirling)用于解决各种数学分析和组合数学问题,斯特林数是两组不同的数,均是18世纪由 詹姆斯·斯特林 引入并以其命名,以第一类斯特林数和第二类斯特林数的称呼区分。此外,有时候也将拉赫数称为第三类斯特林数。

   Stirling数出现在许多组合枚举问题中。对第一类Stirling数 s(n,m)s\left(n,m\right)s(n,m) ,也可记为 [nm]\left [ {\begin{matrix} n \\ m \end{matrix}} \right ][nm​] 。表示将 nnn 个不同元素构成 mmm 个圆排列的方案数。同时还分为无符号第一类Stirling数 su(n,m)s_u\left(n,m\right)su​(n,m) 和有符号第一类Stirling数 ss(n,m)s_s\left(n,m\right)ss​(n,m) 。第二类Stirling数 S(n,m)S\left(n,m\right)S(n,m) ,同时可记为 {nm}\left \{ {\begin{matrix} n\\ m \end{matrix}} \right \}{nm​},表示将 nnn 个不同的元素划分成 mmm 个集合的方案数。(第一类和第二类Stirling数在符号上,一个是小写 sss ,一个是大写 SSS )。拉赫数与斯特林数关系密切,所以有时拉赫数也被称为 第三类斯特林数,将在文末探讨它的定义和一些简单性质。

0x10 第一类斯特林数

0x11 第一类斯特林数的定义

  定义 第一类斯特林数 为将 nnn 个元素,划分为 kkk 个圆排列的方案数,记作 s(n,k)s(n,k)s(n,k),或 [nk]\left[\begin{matrix} n \\ k \end{matrix}\right][nk​]。又根据正负性分为无符号第一类斯特林数 su(n,m)s_u\left(n,m\right)su​(n,m) 和带符号第一类斯特林数 ss(n,m)s_s\left(n,m\right)ss​(n,m)。组合数学中的第一类斯特林数一般指无符号的第一类斯特林数。

  在讲解第一类斯特林数之前,让我们先来了解一下什么是圆排列。

  圆排列定义:圆排列是排列的一种,指从 nnn 个不同元素中取出 mmm(1≤m≤n1≤m≤n1≤m≤n)个不同的元素排列成一个环形,既无头也无尾。两个圆排列相同当且仅当所取元素的个数相同并且元素取法一致,在环上的排列顺序一致。

  圆排列实际上就是群论里的旋转置换,也就是通过旋转任意度数,若相同,则属于同一种方案。我们可以将其想象成一个轮子,怎么转都是一样的,如图11.11 2 3 4 55 4 1 2 3 都算是一种方案,

图11.1

  第一类斯特林数实际上就是求这样一个圆排列的方案数。我们将在接下来的章节讲解两种求解第一类斯特林数的方法,性质及其应用。

0x12 递推求第一类斯特林数(O(n2)\mathcal{O}(n^2)O(n2))

我们考虑如何求解第一类斯特林数,一般首先考虑递推。

考虑这样一个问题:将 111 ~ nnn 的一个排列,划分为 kkk 个圆排列,一共有多少种方案。

我们使用DP的分析方法,分析第 nnn 个数 nnn,有哪些放置方法。

发现一共有两种放置方法:nnn 放到一个新的圆中,或者 nnn 放到已有的圆中。

  • nnn 放到一个新的圆中

此时就意味着前 n−1n-1n−1 个数放到 k−1k-1k−1 个圆中,nnn 放到自己的圆中,也就是第 kkk 个圆,此时的方案数等于 [n−1k−1]\left[\begin{matrix} n-1 \\ k-1 \end{matrix}\right][n−1k−1​]。

  • nnn 放到已有的圆中

即前 n−1n-1n−1 个数放到 kkk 个圆里,第 nnn 个数放到前面 kkk 个圆里,那么对于每一个圆中,如图12.1所示若圆内有 444 个数,那么就会有 444 种放置方案,一共有 n−1n-1n−1 个数所以对于 nnn 来说,一共有 n−1n-1n−1 中放置方案。故此时的方案数等于 (n−1)×[n−1k](n-1)\times \left[\begin{matrix} n-1 \\ k \end{matrix}\right](n−1)×[n−1k​]。

根据加法原理,我们可以得到递推式:

[nk]=[n−1k−1]+(n−1)×[n−1k]\left[\begin{matrix} n \\ k \end{matrix}\right]=\left[\begin{matrix} n-1 \\ k-1 \end{matrix}\right]+(n-1)\times \left[\begin{matrix} n-1 \\ k \end{matrix}\right][nk​]=[n−1k−1​]+(n−1)×[n−1k​]

递推边界:

  • s(n,n)=1(n≥0)s(n,n)=1 (n\ge 0)s(n,n)=1(n≥0)

  • s(n,0)=0(n≥1)s(n,0)=0 (n\ge1)s(n,0)=0(n≥1)

我们将在本文 0x13第一类斯特林数的性质 中证明上述边界性质。

Template A 第一类斯特林数(AcWing 3165)

给定 nnn 和 kkk ,求第一类斯特林数 s(n,k)mod1e9+7s(n,k)\mod1e9+7s(n,k)mod1e9+7 。

时间复杂度为:O(n2)\mathcal{O}(n^2)O(n2)

Code

const int N = 5007, mod = 1e9 + 7;
typedef long long ll;
typedef int itn;
int n, m, k;
ll s[N][N];int main()
{scanf("%d%d", &n, &k);s[0][0] = 1;for(int i = 1; i <= n; ++ i) {for(int j = 1; j <= k; ++ j) {s[i][j] = (s[i - 1][j - 1] + (ll)(i - 1) * s[i - 1][j] % mod) % mod;     }}printf("%lld\n", s[n][k]);return 0;
}

0x13 第一类斯特林数表与斯特林三角

下表为部分无符号斯特林数,要想获得有符号斯特林数,可以通过它们之间的关系式转换:s(n,k)=(−1)n−k[nk]s(n,k)=(-1)^{n-k}\left[\begin{matrix} n \\ k \end{matrix}\right]s(n,k)=(−1)n−k[nk​]

n \ k 0 1 2 3 4 5 6
0 1
1 0 1
2 0 1 1
3 0 2 3 1
4 0 6 11 6 1
5 0 24 50 35 10 1
6 0 120 274 225 85 15 1

   二项式系数 C(n,m)C\left(n,m\right)C(n,m) 可以构成一个杨辉三角(pascal三角形)。同样第一类斯特林数同样也可以构成一个三角如图13.1 所示,我们可以由此分析其性质。

图13.1

0x14 第一类斯特林数的性质

无符号第一类斯特林数性质

性质14.1:su(0,0)=1s_u\left(0,0\right)=1su​(0,0)=1

性质14.2: su(n,0)=0s_u\left(n,0\right)=0su​(n,0)=0

性质14.3: su(n,n)=1s_u\left(n,n\right)=1su​(n,n)=1

性质14.4: su(n,1)=(n−1)!s_u\left(n,1\right)=\left(n-1\right)!su​(n,1)=(n−1)!

性质14.5: su(n,n−1)=Cn2s_u\ (n,n-1)=\text C^{2}_{n}su​ (n,n−1)=Cn2​

性质14.6: su(n,2)=(n−1)!⋅∑i=1n−11is_u\left(n,2\right)=\left(n-1\right)!\cdot\sum\limits_{i=1}^{n-1}\frac{1}{i}su​(n,2)=(n−1)!⋅i=1∑n−1​i1​

性质14.7: su(n,n−2)=2⋅Cn3+3⋅Cn4s_u\left(n,n-2\right)=2\cdot \text C^{3}_{n}+3\cdot \text C^{4}_{n}su​(n,n−2)=2⋅Cn3​+3⋅Cn4​

性质14.8: ∑k=0nsu(n,k)=n!\sum\limits_{k=0}^ns_u\left(n,k\right)=n!k=0∑n​su​(n,k)=n!


性质14.1 ~ 性质14.8 证明:

性质14.1:su(0,0)=1s_u\left(0,0\right)=1su​(0,0)=1

将 000 个数放到 000 个圆排列中,方案数为 111 (经典人为规定)


性质14.2: su(n,0)=0s_u\left(n,0\right)=0su​(n,0)=0

将 nnn 个数放到 000 个圆排列中,一定不存在这样的方法,所以方案数为 000 。


性质14.3: su(n,n)=1s_u\left(n,n\right)=1su​(n,n)=1

将 nnn 个数放到 nnn 个圆排列中,每一个数占用一个圆,方案数为111 。


性质14.4: su(n,1)=(n−1)!s_u\left(n,1\right)=\left(n-1\right)!su​(n,1)=(n−1)!

将 nnn 个数放到 111 个圆排列中,就是 111 ~ nnn 的圆排列的方案数,(n−1)!(n-1)!(n−1)!。

考虑证明:


我们知道圆排列之间是没有关系的,也就是圆与原之间的顺序是没有关系的。

若我们不考虑旋转置换,那么圆排列就变成了普通的排列,那么此时的方案数为 n!n!n! ,即对于第一个数,有 nnn 个数可供选择,对于第二个数, 共有n−1n-1n−1 个数可供选择 ,以此类推,根据乘法原理,共有 n×n−1×n−2×⋯×2×1=n!n\times n-1\times n-2\times\cdots\times 2\times1=n!n×n−1×n−2×⋯×2×1=n! 种。

现在考虑旋转置换带来的重复的操作: 对于 nnn 个数的圆排列,1,2,⋯n1,2,\cdots n1,2,⋯n,nnn 个数可以转 nnn 次,所以对于每一种排法,都会有 nnn 次是重复一样的,所以考虑旋转置换之后的方案数就是 n!n=(n−1)!\cfrac{n!}{n}=(n-1)!nn!​=(n−1)!

综上所述,性质14.4得证 □


性质14.5: su(n,n−1)=Cn2s_u\ (n,n-1)=\text C^{2}_{n}su​ (n,n−1)=Cn2​

将 nnn 个数放到 n−1n-1n−1 个圆排列中的方案数。即有一个圆排列是两个数,其余均为 111 个数的方案数,也就是从 nnn 个数里选择两个数,剩余的 n−2n-2n−2 个数自动每一个数归为一个圆排列,所以总方案数为 Cn2\text C_{n}^{2}Cn2​。


性质14.6: su(n,2)=(n−1)!⋅∑i=1n−11is_u\left(n,2\right)=\left(n-1\right)!\cdot\sum\limits_{i=1}^{n-1}\cfrac{1}{i}su​(n,2)=(n−1)!⋅i=1∑n−1​i1​

将 nnn 个数放到 222 个圆排列中的方案数。

考虑证明:


由于一共只有两个圆排列, 所以我们枚举每一个圆排列内的数的个数是多少。假设第一个圆排列内的数的个数为 iii,则第二个圆排列内的数的个数为 n−in-in−i。

我们考虑选哪 iii 个数放到第一个圆排列中,由 性质14.4 我们可知一个个数为 nnn 的圆排列的总方案数为 (n−1)!(n-1)!(n−1)!,所以我们首先从 nnn 个数里挑选 iii 个数的方案数为 Cni\text C_{n}^{i}Cni​,选出来之后一个圆排列内数的数量为 iii ,方案数为 (i−1)!(i-1)!(i−1)! ,则另一个圆排列的方案数为 (n−i−1)!(n-i-1)!(n−i−1)!。根据乘法原理得总方案数为 Cni×(i−1)!×(n−i−1)!\text C_{n}^{i}\times (i-1)!\times(n-i-1)!Cni​×(i−1)!×(n−i−1)!

但是注意一点,圆排列中,圆与圆之间是不考虑顺序的,也就是说圆与圆之间交换顺序,或者说直接交换元素,是无所谓的,但是我们刚刚计算的时候是划分了第一个圆排列和第二个圆排列交换算作两种不同的方案数来算的,但实际上它们属于同一种方案,所以最后要除以圆的个数:222 。

总方案数为 Cni×(i−1)!×(n−i−1)!2\cfrac{\text C_{n}^{i}\times (i-1)!\times(n-i-1)!}{2}2Cni​×(i−1)!×(n−i−1)!​

考虑化简这个式子:

Cni×(i−1)!×(n−i−1)!2\ \ \ \ \cfrac{\text C_{n}^{i}\times (i-1)!\times(n-i-1)!}{2}    2Cni​×(i−1)!×(n−i−1)!​
=12×n!i!(n−i)!×(i−1)!×(n−i−1)!=\cfrac{1}{2}\times \cfrac{n!}{i!(n-i)!}\times (i-1)!\times(n-i-1)!=21​×i!(n−i)!n!​×(i−1)!×(n−i−1)!
=12×n!i(n−i)=\cfrac{1}{2}\times \cfrac{n!}{i(n-i)}=21​×i(n−i)n!​
=12×(n−1)!×ni(n−i)=\cfrac{1}{2}\times (n-1)!\times \cfrac{n}{i(n-i)}=21​×(n−1)!×i(n−i)n​
=12×(n−1)!×(1i+1n−i)=\cfrac{1}{2}\times (n-1)!\times (\cfrac{1}{i}+\cfrac{1}{n-i})=21​×(n−1)!×(i1​+n−i1​)

故总方案数:

∑i=1n−1Cni×(i−1)!×(n−i−1)!2\ \ \ \ \sum\limits_{i=1}^{n-1}\cfrac{\text C_{n}^{i}\times (i-1)!\times(n-i-1)!}{2}    i=1∑n−1​2Cni​×(i−1)!×(n−i−1)!​
=∑i=1n−112×(n−1)!×(1i+1n−i)=\sum\limits_{i=1}^{n-1}\cfrac{1}{2}\times (n-1)!\times (\cfrac{1}{i}+\cfrac{1}{n-i})=i=1∑n−1​21​×(n−1)!×(i1​+n−i1​)

由于 iii 是从 111 枚举到 n−1n-1n−1 故
1i=11→1n−1\cfrac{1}{i}=\cfrac{1}{1}\to\cfrac{1}{n-1}i1​=11​→n−11​

1n−i=11→1n−1\cfrac{1}{n-i}=\cfrac{1}{1}\to\cfrac{1}{n-1}n−i1​=11​→n−11​

故二者对于最终答案的贡献是相同的,可以看作相等。

即:

∑i=1n−112×(n−1)!×(1i+1n−i)\ \ \ \ \sum\limits_{i=1}^{n-1}\cfrac{1}{2}\times (n-1)!\times (\cfrac{1}{i}+\cfrac{1}{n-i})    i=1∑n−1​21​×(n−1)!×(i1​+n−i1​)
=∑i=1n−112×(n−1)!×2×1i=\sum\limits_{i=1}^{n-1}\cfrac{1}{2}\times (n-1)!\times 2\times\cfrac{1}{i}=i=1∑n−1​21​×(n−1)!×2×i1​
=∑i=1n−1(n−1)!×1i=\sum\limits_{i=1}^{n-1} (n-1)!\times \cfrac{1}{i}=i=1∑n−1​(n−1)!×i1​ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ %                             ⋯\cdots⋯ ⋯\cdots⋯((n−1)!(n-1)!(n−1)! 是常数,可以提出来)
=(n−1)!⋅∑i=1n−11i=\left(n-1\right)!\cdot\sum\limits_{i=1}^{n-1}\cfrac{1}{i}=(n−1)!⋅i=1∑n−1​i1​

综上所述,性质14.7 得证 □


性质14.7: su(n,n−2)=2⋅Cn3+3⋅Cn4s_u\left(n,n-2\right)=2\cdot \text C^{3}_{n}+3\cdot \text C^{4}_{n}su​(n,n−2)=2⋅Cn3​+3⋅Cn4​

将 nnn 个数放到 n−2n-2n−2 个圆排列中的方案数。

我们分为两种情况讨论

● \ %  将 n−3n-3n−3 个数放入 n−3n-3n−3 个圆排列中,每个圆排列内的个数为 111 的,剩余的三个数,放入一个个数为 333 的圆排列中,共 n−2n-2n−2 个圆排列。

首先是从 nnn 个数中选择 333 个数的方案数,并且这个个数为 333 的圆排列中排列的方案数为 (3−1)!=2(3-1)!=2(3−1)!=2,这种情况的方案为 Cn3×2\text C^{3}_{n}\times 2Cn3​×2

● \ %  将 n−4n-4n−4 个数放入 n−4n-4n−4 个个数为 111 的圆排列中,剩余 444 个数,放入两个个数为 222 的圆排列中。

总方案数,首先考虑从 nnn 个数中选择 444 个数的方案数为:Cn4\text C^{4}_{n}Cn4​,接下来就是将这 444 个数划分为两组,我们每次选择两个数,与剩余的两个数与这两个数是对偶的,所以将 444 个数划分为两组的方案数为 12C42=3\cfrac{1}{2}\text C^{2}_{4}=321​C42​=3,故这种情况的方案数为 3×Cn43\times \text C^{4}_{n}3×Cn4​。

综上所诉,总方案数 su(n,n−2)=2⋅Cn3+3⋅Cn4s_u\left(n,n-2\right)=2\cdot \text C^{3}_{n}+3\cdot \text C^{4}_{n}su​(n,n−2)=2⋅Cn3​+3⋅Cn4​ □


性质14.8: ∑k=0nsu(n,k)=n!\sum\limits_{k=0}^ns_u\left(n,k\right)=n!k=0∑n​su​(n,k)=n!

意味着斯特林数的和为 n!n!n! ,具体证明需要用到第一类斯特林数的生成函数——上升幂,将在 0x16 第一类斯特林数的生成函数 中对 性质14.8 予以证明。

0x15 上升幂与下降幂

我们记 上升阶乘幂(上升幂)

xn‾=∏k=0n−1(x+k)=x(x+1)(x+2)⋯(x+n−1)x^{\overline{n}}=\prod\limits_{k=0}^{n-1} (x+k)=x(x+1)(x+2)\cdots(x+n-1)xn=k=0∏n−1​(x+k)=x(x+1)(x+2)⋯(x+n−1)

普通的幂就是 x×x×x×⋯x\times x\times x\times \cdotsx×x×x×⋯,上升幂就可以形象地理解为 xxx 越乘越大,在往上升。

我们就可以利用下面的恒等式将上升幂转化为普通幂:

xn‾=∑k=0n[nk]xkx^{\overline{n}}=\sum\limits_{k=0}^{n} \begin{bmatrix}n\\ k\end{bmatrix} x^kxn=k=0∑n​[nk​]xk

如果将普通幂转化为上升幂,则有下面的恒等式:

xn=∑k{nk}(−1)n−kxk‾x^n=\sum_{k} \begin{Bmatrix}n\\ k\end{Bmatrix} (-1)^{n-k} x^{\overline{k}}xn=k∑​{nk​}(−1)n−kxk

我们记 下降阶乘幂(下降幂)

xn‾=x!(x−n)!=∏k=0n−1(x−k)x^{\underline{n}}=\dfrac{x!}{(x-n)!}=\prod_{k=0}^{n-1} (x-k)xn​=(x−n)!x!​=k=0∏n−1​(x−k) 。
则可以利用下面的恒等式将普通幂转化为下降幂:

xn=∑k{nk}xk‾x^n=\sum_{k} \begin{Bmatrix}n \\ k\end{Bmatrix} x^{\underline{k}}xn=k∑​{nk​}xk​

如果将下降幂转化为普通幂,则有下面的恒等式:

xn‾=∑k[nk](−1)n−kxkx^{\underline{n}}=\sum_{k} \begin{bmatrix}n \\ k\end{bmatrix} (-1)^{n-k} x^kxn​=k∑​[nk​](−1)n−kxk

多项式下降阶乘幂表示与多项式点值表示的关系

在这里,多项式的下降阶乘幂表示就是用

f(x)=∑i=0nbixi‾f(x)=\sum\limits_{i=0}^nb_i{x^{\underline{i}}}f(x)=i=0∑n​bi​xi​

的形式表示一个多项式,而点值表示就是用 n+1n+1n+1 个点

(i,ai),i=0⋯n(i,a_i),i=0\cdots n(i,ai​),i=0⋯n

来表示一个多项式。
显然,下降阶乘幂 bbb 和点值 aaa 间满足这样的关系:

ak=∑i=0nbiki‾a_k=\sum\limits_{i=0}^{n}b_ik^{\underline{i}}ak​=i=0∑n​bi​ki​

ak=∑i=0nbik!(k−i)!akk!=∑i=0kbi1(k−i)!\begin{aligned} a_k&=\sum\limits_{i=0}^{n}\dfrac{b_ik!}{(k-i)!}\\\dfrac{a_k}{k!}&=\sum\limits_{i=0}^kb_i\dfrac{1}{(k-i)!} \end{aligned}ak​k!ak​​​=i=0∑n​(k−i)!bi​k!​=i=0∑k​bi​(k−i)!1​​

  很明显这是一个卷积形式的式子,我们可以在 O(nlogn)\mathcal{O}(nlogn)O(nlogn) 的时间复杂度内完成点值和下降阶乘幂的互相转化。

0x16 第一类斯特林数的生成函数

  还没有学过生成函数的同学请点击链接学习一下:《小学生都能看懂的生成函数从入门到升天教程》《生成函数全家桶》

  有无符号斯特林数分别表现为其升阶函数和降阶函数的各项系数(类似于二项式系数),形式如下:

  有符号斯特林数的生成函数为降阶函数(下降幂):

xn‾=xn↓=x(x−1)(x−2)⋯(x−n+1)=∑k=0nss(n,k)xkx^{\underline n}=x^{n\downarrow}=x\left(x-1\right)\left(x-2\right)\cdots\left(x-n+1\right)=\sum_{k=0}^ns_s\left(n,k\right)x^kxn​=xn↓=x(x−1)(x−2)⋯(x−n+1)=k=0∑n​ss​(n,k)xk

  无符号斯特林数的的生成函数为升阶函数(上升幂):

xnˉ=xn↑=x(x+1)(x+2)⋯(x+n−1)=∑k=0nsu(n,k)xkx^{\bar n}=x^{n\uparrow}=x\left(x+1\right)\left(x+2\right)\cdots\left(x+n-1\right)=\sum_{k=0}^ns_u\left(n,k\right)x^kxnˉ=xn↑=x(x+1)(x+2)⋯(x+n−1)=k=0∑n​su​(n,k)xk

考虑证明:


  这里仅简单证明一下无符号斯特林数生成函数升阶函数,有符号斯特林数的生成函数的证明方法类同,留给读者自己下来证明。

考虑使用归纳法:

我们知道上升幂

xnˉ=xn↑=x(x+1)(x+2)⋯(x+n−1)=∑k=0nsu(n,k)xkx^{\bar n}=x^{n\uparrow}=x\left(x+1\right)\left(x+2\right)\cdots\left(x+n-1\right)=\sum_{k=0}^ns_u\left(n,k\right)x^kxnˉ=xn↑=x(x+1)(x+2)⋯(x+n−1)=k=0∑n​su​(n,k)xk

我们知道若上升幂是第一类无符号斯特林数的生成函数,则意味着 xkx^kxk 的系数即为 [nk]\left [ {\begin{matrix} n \\ k \end{matrix}} \right ][nk​] 的斯特林数。

因此我们需要证明 x(x+1)(x+2)⋯(x+n−1)x\left(x+1\right)\left(x+2\right)\cdots\left(x+n-1\right)x(x+1)(x+2)⋯(x+n−1) 中 xkx^kxk 的系数等于 [nk]\left [ {\begin{matrix} n \\ k \end{matrix}} \right ][nk​] 。

生成函数中, xkx^kxk 的系数,意味着选择若干个 xxx 的次幂,它们的系数的乘积。

图16.1

如图16.1 所示,我们选了 kkk 个 xxx,所有选了 xxx 的系数乘积,乘上没有选择 xxx ,选择了常数的乘积。

假设当前已经处理了前 n−1n-1n−1 项,则对于最后一项(第 nnn 项):

  • 若最后的 (x−n−1)(x - n - 1)(x−n−1) 选择的是 xxx ,则前面就要选择 k−1k-1k−1 个 xxx ,系数为前 n−1n- 1n−1 项中选出 k−1k-1k−1 个 xxx 的系数。

  • 若最后的 (x−n−1)(x - n - 1)(x−n−1) 选择的是 n−1n-1n−1 ,则系数为前面 n−1n- 1n−1 项中选择 kkk 个 xxx 的系数乘上当前选择的 n−1n-1n−1 。

即可推出递推式:

[nk]=[n−1k−1]+(n−1)×[n−1k]\left[\begin{matrix} n \\ k \end{matrix}\right]=\left[\begin{matrix} n-1 \\ k-1 \end{matrix}\right]+(n-1)\times \left[\begin{matrix} n-1 \\ k \end{matrix}\right][nk​]=[n−1k−1​]+(n−1)×[n−1k​]

我们发现该式即为 斯特林数的递推式。

综上所述,上升幂即为斯特林数的生成函数,证明得证。□


由于生成函数对于任意的 xxx 而言,均成立,所以我们可设 x=1x=1x=1

xnˉ=xn↑=x(x+1)(x+2)⋯(x+n−1)=n!x^{\bar n}=x^{n\uparrow}=x\left(x+1\right)\left(x+2\right)\cdots\left(x+n-1\right)=n!xnˉ=xn↑=x(x+1)(x+2)⋯(x+n−1)=n!

由于xnˉ=xn↑=∑k=0nsu(n,k)xkx^{\bar n}=x^{n\uparrow}=\sum_{k=0}^ns_u\left(n,k\right)x^kxnˉ=xn↑=k=0∑n​su​(n,k)xk

则 ∑k=0nsu(n,k)xk=n!\sum_{k=0}^ns_u\left(n,k\right)x^k=n!∑k=0n​su​(n,k)xk=n! ,故 性质14.8 得证。□


0x17 生成函数求第一类斯特林数(O(nlogn)\mathcal{O}(nlogn)O(nlogn))

  我们之前已经介绍过了使用递推的方法求解斯特林数,但是复杂度 O(n2)O(n^2)O(n2),可以解决绝大多数的问题,但是效率有些糟糕。我们上面介绍了斯特林数的生成函数,上升幂,很明显,我们可以直接使用多项式求解该生成函数,将时间复杂度降到 O(nlogn)\mathcal{O}(nlogn)O(nlogn),可以看出,生成函数+多项式是组合数学的一大利器。

  还没有学过多项式科技的同学请点击链接学习一下:【学习笔记】多项式全家桶!!!(公式模板大全)

Problem A 第一类斯特林数·行( luogu P5408 )

第一类斯特林数 [nm]\begin{bmatrix}n\\ m\end{bmatrix}[nm​] 表示将 nnn 个不同元素构成 mmm 个圆排列的数目。

给定 nnn ,对于所有的整数 i∈[0,n]i\in[0,n]i∈[0,n] ,你要求出 [ni]\begin{bmatrix}n\\ i\end{bmatrix}[ni​] 。

由于答案会非常大,所以你的输出需要对 167772161167772161167772161 (225×5+12^{25}\times 5+1225×5+1 ,是一个质数)取模。

输入格式
一行一个正整数 nnn ,意义见题目描述。

输出格式
共一行 n+1n+1n+1 个非负整数。

你需要按顺序输出[n0],[n1],[n2],…,[nn]\begin{bmatrix}n\\ 0\end{bmatrix},\begin{bmatrix}n\\ 1\end{bmatrix},\begin{bmatrix}n\\ 2\end{bmatrix},\dots,\begin{bmatrix}n\\ n\end{bmatrix}[n0​],[n1​],[n2​],…,[nn​]的值。

Solution

我们知道无符号第一类斯特林数的生成函数为上升幂:

xnˉ=xn↑=x(x+1)(x+2)⋯(x+n−1)=∑k=0nsu(n,k)xkx^{\bar n}=x^{n\uparrow}=x\left(x+1\right)\left(x+2\right)\cdots\left(x+n-1\right)=\sum_{k=0}^ns_u\left(n,k\right)x^kxnˉ=xn↑=x(x+1)(x+2)⋯(x+n−1)=k=0∑n​su​(n,k)xk

也就是说我们只需要求出上升幂 xnˉx^{\bar{n}}xnˉ 即可推出第一类斯特林数的值。

很明显我们可以使用倍增法,利用多项式来求解。

显然有

x2nˉ=xnˉ(x+n)nˉx^{\bar{2n}}=x^{\bar{n}}(x+n)^{\bar{n}}x2nˉ=xnˉ(x+n)nˉ

也就是

∏i=02n−1(x+i)=∏i=0n−1(x+i)∏i=0n−1(x+n+i)\prod\limits_{i=0}^{2n-1}(x+i)=\prod\limits_{i=0}^{n-1}(x+i)\prod\limits_{i=0}^{n-1}(x+n+i)i=0∏2n−1​(x+i)=i=0∏n−1​(x+i)i=0∏n−1​(x+n+i)

(展开后等式两边相等)

假设我们已经知道了 xnˉx^{\bar{n}}xnˉ ,那么瓶颈就在于如何算出 (x+n)nˉ(x+n)^{\bar{n}}(x+n)nˉ

设 f(x)=xnˉf(x)=x^{\bar{n}}f(x)=xnˉ,那么 (x+n)nˉ(x+n)^{\bar{n}}(x+n)nˉ 就是 f(x+n)f(x+n)f(x+n)

那么问题就变为怎么从多项式 f(x)f(x)f(x) 推到多项式 f(x+n)f(x+n)f(x+n),也就是说我们知道了一个 nnn 次多项式 f(x)f(x)f(x),如何快速计算出 f(x+n)f(x+n)f(x+n) 。

假设 f(x)f(x)f(x) 的第 iii 项系数为 aia_iai​ ,即 ai=[xi]f(x)a^i=[x^i]f(x)ai=[xi]f(x)

则:

f(x+n)=∑i=0nai(x+n)i=∑i=0nai∑j=0ixjni−j(ij)=∑j=0nxj∑i=jnaini−j(ij)=∑j=0nxjj!∑i=jn(aii!)ni−j(i−j)!\begin{aligned} f(x+n)&=\sum_{i=0}^{n}a_i(x+n)^i \\ &= \sum_{i=0}^{n} a_i \sum_{j=0}^i x^j n^{i-j} \binom i j \\ &= \sum_{j=0}^n x^j \sum_{i=j}^n a_i n^{i-j} \binom i j \\&=\sum_{j=0}^n\ \cfrac{x^j}{j!}\ \sum_{i=j}^n\ (a_ii!)\ \cfrac{n^{i-j}}{(i-j)!} \end{aligned}f(x+n)​=i=0∑n​ai​(x+n)i=i=0∑n​ai​j=0∑i​xjni−j(ji​)=j=0∑n​xji=j∑n​ai​ni−j(ji​)=j=0∑n​ j!xj​ i=j∑n​ (ai​i!) (i−j)!ni−j​​

我们设多项式 A(i)=aii!,B(i)=nii!A(i)=a_ii!,B(i)=\cfrac{n^i}{i!}A(i)=ai​i!,B(i)=i!ni​ ,就有:

f(x+n)=∑j=0nxjj!∑i=jnA(i)×B(i−j)=∑j=0nxjj!∑i=0n−jA(i+j)×B(i)=∑j=0nxjj!∑i=0n−jA′(n−j−i)×B(i)\begin{aligned} f(x+n)&=\sum_{j=0}^n\ \cfrac{x^j}{j!}\ \sum_{i=j}^n A(i) \times B(i-j)\\ &= \sum_{j=0}^n\ \cfrac{x^j}{j!}\ \sum_{i=0}^{n-j} A(i+j) \times B(i) \\ &= \sum_{j=0}^n\ \cfrac{x^j}{j!}\ \sum_{i=0}^{n-j} A'(n-j-i) \times B(i) \end{aligned}f(x+n)​=j=0∑n​ j!xj​ i=j∑n​A(i)×B(i−j)=j=0∑n​ j!xj​ i=0∑n−j​A(i+j)×B(i)=j=0∑n​ j!xj​ i=0∑n−j​A′(n−j−i)×B(i)​

其中多项式 A′A'A′ 表示 AAA 反转后的多项式。

很明显这里就是两个多项式的卷积,我们可以直接使用多项式乘法求解,O(nlog⁡n)\mathcal{O}(n \log n)O(nlogn) 的时间复杂度求出 f(x+n)f(x+n)f(x+n) 。

这样我们就得到了快速求得 f(x+n)f(x+n)f(x+n) 的方法,最后我们只需要再用一次多项式乘法求一下 f(x)f(x+n)f(x)f(x+n)f(x)f(x+n) 即可。

总时间复杂度使用倍增,和FFT的时间复杂度一样, T(n)=T(n2)+O(nlog⁡n)=O(nlog⁡n)T(n)=T(\cfrac{n}{2})+\mathcal{O}(n\log n)=\mathcal{O}(n \log n)T(n)=T(2n​)+O(nlogn)=O(nlogn)

Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>using namespace std;
#define int long long
typedef long long ll;
const ll mod = 167772161;
ll G = 3, invG;
const int N = 1200000;
ll qpow(ll b, int n) {ll res = 1;while (n) {if (n & 1)res = res * b % mod;b = b * b % mod;n >>= 1;}return res;
}
int read() {int x = 0;char ch = getchar();while (!isdigit(ch))ch = getchar();while (isdigit(ch))x = (x * 10 + (ch - '0')) % mod, ch = getchar();return x;
}
int R[N];
void NTT(ll *f, int n, int fl) {for (int i = 0; i < n; ++i)if (i < R[i])swap(f[i], f[R[i]]);for (int p = 2; p <= n; p <<= 1) {int len = (p >> 1);ll w = qpow((fl == 0) ? G : invG, (mod - 1) / p);for (int st = 0; st < n; st += p) {ll buf = 1, tmp;for (int i = st; i < st + len; ++i) {tmp = buf * f[i + len] % mod;f[i + len] = (f[i] - tmp + mod) % mod;f[i] = (f[i] + tmp) % mod;buf = buf * w % mod;}}}if (fl == 1) {ll invN = qpow(n, mod - 2);for (int i = 0; i < n; ++i)f[i] = (f[i] * invN) % mod;}
}
void Mul(ll *f, ll *g, int n, int m) {m += n;n = 1;while (n < m)n <<= 1;for (int i = 0; i < n; ++i)R[i] = (R[i >> 1] >> 1) | ((i & 1) ? (n >> 1) : 0);NTT(f, n, 0);NTT(g, n, 0);for (int i = 0; i < n; ++i)f[i] = f[i] * g[i] % mod;NTT(f, n, 1);
}
ll inv[N], fac[N];
ll w[N], a[N], b[N], g[N];
void Solve(ll *f, int m) {if (m == 1)return f[1] = 1, void(0);if (m & 1) {Solve(f, m - 1);for (int i = m; i >= 1; --i)f[i] = (f[i - 1] + f[i] * (m - 1) % mod) % mod;f[0] = f[0] * (m - 1) % mod;} else {int n = m / 2;ll res = 1;Solve(f, n);for (int i = 0; i <= n; ++i)a[i] = f[i] * fac[i] % mod, b[i] = res * inv[i] % mod, res = res * n % mod;reverse(a, a + n + 1);Mul(a, b, n + 1, n + 1);for (int i = 0; i <= n; ++i)g[i] = inv[i] * a[n - i] % mod;Mul(f, g, n + 1, n + 1);int limit = 1;while (limit < (n + 1) << 1)limit <<= 1;for (int i = n + 1; i < limit; ++i)a[i] = b[i] = g[i] = 0;for (int i = m + 1; i < limit; ++i)f[i] = 0;}
}
ll f[N];
void init(int n) {fac[0] = 1;for (int i = 1; i <= n; ++i)fac[i] = 1ll * fac[i - 1] * i % mod;inv[n] = qpow(fac[n], mod - 2);for (int i = n - 1; i >= 0; --i)inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
}
signed main() {invG = qpow(G, mod - 2);int n, k = 0;cin >> n;init(n + n);Solve(f, n);for (int i = 0; i <= n; ++i)printf("%lld ", f[i]);return 0;
}

Problem B 第一类斯特林数·列( luogu P5409 )

第一类斯特林数 [nm]\begin{bmatrix}n\\ m\end{bmatrix}[nm​] 表示将 nnn 个不同元素构成 mmm 个圆排列的数目。

给定 n,kn,kn,k ,对于所有的整数 i∈[0,n]i\in[0,n]i∈[0,n] ,你要求出 [ik]\begin{bmatrix}i\\ k\end{bmatrix}[ik​] 由于答案会非常大,所以你的输出需要对 167772161167772161167772161 (225×5+12^{25}\times 5+1225×5+1,是一个质数)取模。

输入格式
一行两个正整数 n,kn,kn,k ,意义见题目描述。

输出格式
共一行 n+1n+1n+1 个非负整数。

你需要按顺序输出[0k],[1k],[2k],…,[nk]\begin{bmatrix}0\\ k\end{bmatrix},\begin{bmatrix}1\\ k\end{bmatrix},\begin{bmatrix}2\\ k\end{bmatrix},\dots,\begin{bmatrix}n\\ k\end{bmatrix}[0k​],[1k​],[2k​],…,[nk​]的值。

Solution

我们可以用指数型生成函数解决该问题。注意,由于递推公式和行有关,我们不能利用递推公式计算同列的第一类斯特林数。

显然,单个轮换的指数型生成函数为

F(x)=∑i=1n(i−1)!xii!=∑i=1nxiiF(x)=\sum\limits_{i=1}^n\dfrac{(i-1)!x^i}{i!}=\sum\limits_{i=1}^n\dfrac{x^i}{i}F(x)=i=1∑n​i!(i−1)!xi​=i=1∑n​ixi​

它的 kkk 次幂就是 [ik]\begin{bmatrix}i\\k\end{bmatrix}[ik​] 的指数型生成函数。直接计算即可。

时间复杂度:O(nlogn)\mathcal O(nlogn)O(nlogn)

int main() {scanf("%d%d", &n, &k);fact[0] = 1;for (int i = 1; i <= n; ++i)fact[i] = (ll)fact[i - 1] * i % mod;ifact[n] = qpow(fact[n], mod - 2);for (int i = n - 1; i >= 0; -- i)ifact[i] = (ll)ifact[i + 1] * (i + 1) % mod;poly f(n + 1);for (int i = 1; i <= n; ++ i)f[i] = (ll)fact[i - 1] * ifact[i] % mod;f = poly_exp(log(f >> 1) * k) << k, f.resize(n + 1);for (int i = 0; i <= n; ++ i)printf("%lld ", 1ll * f[i] * fact[i] % mod * ifact[k] % mod);return 0;
}

0x18 简单应用举例

  第一类Stirling除了表示可以表示升阶函数和降阶函数的系数之外还可以应用到一些实际问题上。例如很经典的解锁仓库问题

  问题说明如下:有 nnn 个仓库,每个仓库有两把钥匙,共 2n2n2n 把钥匙。同时又有 nnn 位官员。问如何放置钥匙使得所有官员都能够打开所有仓库?(只考虑钥匙怎么放到仓库中,而不考虑官员拿哪把钥匙。)那如果官员分成 mmm 个不同的部,部中的官员数量和管理的仓库数量一致。那么有多少方案使得,同部的所有官员可以打开所有本部管理的仓库,而无法打开其他部管理的仓库?(同样只考虑钥匙的放置。)

  第一问很经典,就是打开将钥匙放入仓库构成一个环:111 号仓库放 222 号钥匙, 222 号仓库放 333 号钥匙…… nnn 号仓库放 111 号钥匙。这样只要手里有一把钥匙,就可以打开所有仓库的门。这种情况相当于钥匙和仓库编号构成一个圆排列方案数是 (n−1)!(n-1)!(n−1)! 种。

  而第二问就对应的将 nnn 个元素分成 mmm 个圆排列,因为本部只能打开本部的仓库,又必须全部都能打开,所以就相当于划分成了 mmm 个圆排列,方案数就是第一类无符号斯特林数 su(n,m)s_u\left(n,m\right)su​(n,m)。如果要考虑官员分配的情况,只需再乘上 n!n!n! 即可。

0x19 竞赛例题选讲

Problem A [FJOI2016]建筑师( luogu P4609 )

建筑工,伐伐伐伐伐木工

小 ZZZ 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 nnn 个建筑,每个建筑的高度是 111 到 nnn 之间的一个整数。

小 ZZZ 有很严重的强迫症,他不喜欢有两个建筑的高度相同。

另外小 ZZZ 觉得如果从最左边(所有建筑都在右边)看能看到 AAA 个建筑,从最右边(所有建筑都在左边)看能看到 BBB 个建筑,这样的建筑群有着独特的美感。

现在,小 ZZZ 想知道满足上述所有条件的建筑方案有多少种?

如果建筑 iii 的左(右)边没有任何建造比它高,则建筑 iii 可以从左(右)边看到。

两种方案不同,当且仅当存在某个建筑在两种方案下的高度不同。

Solution

0x20 第二类斯特林数

0x21 第二类斯特林数的定义

  第二类斯特林数实际上是集合的一个拆分,表示将 nnn 个不同的元素拆分成 mmm 个集合间有序(可以理解为集合上有编号且集合不能为空)的方案数,记为 S(n,m)S\left(n,m\right)S(n,m) (这里是大写的)或者 {nm}\left \{ {\begin{matrix} n\\ m \end{matrix}} \right \}{nm​} 。和第一类斯特林数不同的是,这里的集合内部是不考虑次序的,而圆排列圆的内部是有序的。常常用于解决组合数学中的几类放球模型。描述为:将 nnn 个不同的球放入 mmm 个无差别的盒子中,要求盒子非空,有几种方案?

第二类斯特林数要求盒子是无区别的,所以可以得到其方案数公式:

S(n,m)=1m!∑k=0m(−1)k(mk)(m−k)nS\left(n,m\right)=\cfrac{1}{m!}\sum\limits_{k=0}^m\left(-1\right)^k\binom{m}{k}\left(m-k\right)^nS(n,m)=m!1​k=0∑m​(−1)k(km​)(m−k)n

0x22 递推求第二类斯特林数(O(n2)\mathcal O(n^2)O(n2))

第二类斯特林数的推导和第一类斯特林数类似。

我们继续使用DP的分析方法,假设要把 nnn 个元素分成 kkk 个集合,我们来分析第 nnn 个数 nnn,有哪些放置方法。

发现还是一共有两种放置方法:nnn 放到一个新的集合中,或者 nnn 放到已有的集合中。

  • nnn 放到一个新的集合中

此时就意味着前 n−1n-1n−1 个数放到 k−1k-1k−1 个集合中,nnn 放到自己的集合中,也就是第 kkk 个集合,此时的方案数等于 {n−1k−1}\left\{\begin{matrix} n-1 \\ k-1 \end{matrix}\right\}{n−1k−1​}。

  • nnn 放到已有的集合中

即前 n−1n-1n−1 个数放到 kkk 个集合里,第 nnn 个数放到前面 kkk 个集合里,那么对于每一个集合中,由于内部是无序的,而集合间是有序的,所以相当于将 kkk 放到 kkk 个箱子里,有 kkk 种选择。故此时的方案数等于 k×{n−1k}k\times \left\{\begin{matrix} n-1 \\ k \end{matrix}\right\}k×{n−1k​}。

故可以得到第二类斯特林数的递推公式:

{nk}={n−1k−1}+k×{n−1k}\left\{\begin{matrix} n \\ k \end{matrix}\right\}=\left\{\begin{matrix} n-1 \\ k-1 \end{matrix}\right\}+k\times \left\{\begin{matrix} n-1 \\ k \end{matrix}\right\}{nk​}={n−1k−1​}+k×{n−1k​}

边界条件:

S(n,n)=1,p≥0S(n,n)=1 ,p\ge 0S(n,n)=1,p≥0

S(n,0)=0,n≥1S(n,0)=0,n\ge1S(n,0)=0,n≥1

Template A 第二类斯特林数(AcWing 3166)

给定 nnn 和 kkk ,求第二类斯特林数 S(n,k)mod1e9+7S(n,k)\mod1e9+7S(n,k)mod1e9+7 。

时间复杂度为:O(n2)\mathcal{O}(n^2)O(n2)

typedef long long ll;
typedef int itn;
const int N = 5007, mod = 1e9 + 7;
int n, m, k;
int S[N][N];
int main()
{scanf("%d%d", &n, &k);S[0][0] = 1;S[n][0] = 0;for(int i = 1; i <= n; ++ i) {for(int j = 1; j <= k; ++ j) {S[i][j] = (S[i- 1][j - 1] + 1ll * j * S[i - 1][j]) % mod;//公式中的 k 是当前的 k}}cout << S[n][k] << endl;return 0;
}

0x23 第二类斯特林数表与斯特林三角

n 第二类斯特林数
n=0 1
n=1 0 1
n=2 0 1 1
n=3 0 1 3 1
n=4 0 1 7 6 1
n=5 0 1 15 25 10 1
n=6 0 1 31 90 65 15 1
n=7 0 1 63 301 350 140 21 1
n=8 0 1 127 966 1701 1050 266 28 1
n=9 0 1 255 3025 7770 6951 2646 462 36 1

0x24 第二类斯特林数的性质

第二类斯特林数性质

性质24.1:S(n,0)=0nS\left(n,0\right)=0^nS(n,0)=0n

性质24.2: S(n,1)=1S\left(n,1\right)=1S(n,1)=1

性质24.3: S(n,n)=1S\left(n,n\right)=1S(n,n)=1

性质24.4: S(n,2)=2n−1−1S\left(n,2\right)=2^{n-1}-1S(n,2)=2n−1−1

性质24.5: S(n,n−1)=C(n,2)S\left(n,n-1\right)=C(n,2)S(n,n−1)=C(n,2)

性质24.6: S(n,n−2)=C(n,3)+3⋅C(n,4)S\left(n,n-2\right)=C(n,3)+3\cdot C(n,4)S(n,n−2)=C(n,3)+3⋅C(n,4)

性质24.7: S(n,3)=12(3n−1+1)−2n−1S\left(n,3\right)=\frac{1}{2}(3^{n-1}+1)-2^{n-1}S(n,3)=21​(3n−1+1)−2n−1

性质24.8: S(n,n−3)=C(n,4)+10⋅C(n,5)+15⋅C(n,6)S\left(n,n-3\right)=C(n,4)+10\cdot C(n,5)+15\cdot C(n,6)S(n,n−3)=C(n,4)+10⋅C(n,5)+15⋅C(n,6)

性质24.9: ∑k=0nS(n,k)=Bn\sum\limits_{k=0}^nS(n,k)=B_nk=0∑n​S(n,k)=Bn​,其中 BnB_nBn​ 是贝尔数

推论24.10: 若 n<mn<mn<m, ∑k=0m(−1)k(mk)(m−k)n=0\sum\limits_{k=0}^m\left(-1\right)^k\binom{m}{k}\left(m-k\right)^n=0k=0∑m​(−1)k(km​)(m−k)n=0

推论24.11: 因为 S(m,m)=1S(m,m)=1S(m,m)=1,所以有 ∑k=0m(−1)k(km)(m−k)m=m!\sum\limits_{k=0}^m\left(-1\right)^k(_k^m)\left(m-k\right)^m=m!k=0∑m​(−1)k(km​)(m−k)m=m!

推论24.12: nk=∑i=0kS(k,i)×i!×Cnin^k=\sum\limits_ { i=0}^k S(k,i)×i!×C_{n}^ink=i=0∑k​S(k,i)×i!×Cni​


性质24.1 ~ 推论24.12 证明:

待更…

0x24 第二类斯特林数的生成函数

普通型生成函数

G0(S(n,k))=∑n⩾kS(n,k)xn=xk(1−x)(1−2x)⋯(1−kx)=xk∏r=1k(1−rx)\mathbf{G}_{0}(S(n,k))=\sum_{n \geqslant k} S(n, k) x^{n}=\frac{x^{k}}{(1-x)(1-2 x) \cdots(1-k x)}=\frac{x^k}{\prod_{r=1}^k{(1-rx)}}G0​(S(n,k))=n⩾k∑​S(n,k)xn=(1−x)(1−2x)⋯(1−kx)xk​=∏r=1k​(1−rx)xk​

考虑证明:



Bk(x)=∑n⩾kS(n,k)xnB_{k}(x)=\sum_{n \geqslant k} S(n, k) x^{n}Bk​(x)=n⩾k∑​S(n,k)xn

由上述递推关系,两边同乘以 xnx^nxn,并对 nnn 从 kkk 到+∞+\infty+∞求和,结合生成函数定义,得:

Bk(x)=xBk−1(x)+kxBk(x)B_{k}(x)=x B_{k-1}(x)+k x B_{k}(x)Bk​(x)=xBk−1​(x)+kxBk​(x)

于是我们得到:

Bk(x)=xBk−1(x)1−kx=x2Bk−2(x)(1−kx)(1−(k−1)x)=…=xk∏r=1k(1−rx)B_{k}(x)=\frac{x B_{k-1}(x)}{1-k x}=\frac{x^{2} B_{k-2}(x)}{(1-k x)(1-(k-1) x)}=\ldots=\frac{x^{k}}{\prod_{r=1}^{k}(1-r x)}Bk​(x)=1−kxxBk−1​(x)​=(1−kx)(1−(k−1)x)x2Bk−2​(x)​=…=∏r=1k​(1−rx)xk​

指数型生成函数

Ge(S(n,k))=∑n⩾kS(n,k)⋅xnn!=(ex−1)kk!\mathbf{G}_{e}(S(n,k))=\sum_{n \geqslant k} S(n, k) \cdot \frac{x^{n}}{n !}=\frac{\left(e^{x}-1\right)^{k}}{k !}Ge​(S(n,k))=n⩾k∑​S(n,k)⋅n!xn​=k!(ex−1)k​

0x25 第二类斯特林数的通项公式

第二类斯特林数的通项公式

{nm}=∑i=0m(−1)m−iini!(m−i)!\begin{Bmatrix}n\\m\end{Bmatrix}=\sum\limits_{i=0}^m\dfrac{(-1)^{m-i} i^n}{i!(m-i)!}{nm​}=i=0∑m​i!(m−i)!(−1)m−iin​

考虑证明:

我们可以使用容斥原理来简单证明该通项公式。设将 nnn 个两两不同的元素,划分到 kkk 个两两不同的集合(允许空集)的方案数为 GiG_iGi​,将 nnn 个两两不同的元素,划分到 kkk 个两两不同的非空集合(不允许空集)的方案数为 FiF_iFi​。

显然有:

Gi=knGi=∑j=0i(ij)FjG_i=k^n\\ G_i=\sum\limits_{j=0}^i\binom{i}{j}F_jGi​=knGi​=j=0∑i​(ji​)Fj​

0x26 生成函数求第二类斯特林数(O(nlogn)\mathcal O(nlogn)O(nlogn))

Problem A 第二类斯特林数·行 ( luogu P5395 )

第二类斯特林数{nm}\begin{Bmatrix} n \\m \end{Bmatrix}{nm​}表示把 nnn 个不同元素划分成 mmm 个相同的集合中(不能有空集)的方案数。

给定 nnn ,对于所有的整数 i∈[0,n]i\in[0,n]i∈[0,n] ,你要求出{ni}\begin{Bmatrix} n \\i \end{Bmatrix}{ni​}由于答案会非常大,所以你的输出需要对 167772161167772161167772161(225×5+12^{25}\times 5+1225×5+1,是一个质数)取模。

输入格式

一行一个正整数 nnn,意义见题目描述。

输出格式

共一行 n+1n+1n+1 个非负整数。

你需要按顺序输出{n0},{n1},{n2},…,{nn}\begin{Bmatrix} n \\0 \end{Bmatrix},\begin{Bmatrix} n \\1 \end{Bmatrix},\begin{Bmatrix} n \\2 \end{Bmatrix},\dots,\begin{Bmatrix} n \\n \end{Bmatrix}{n0​},{n1​},{n2​},…,{nn​}的值。

Solution

“同一行”的第二类斯特林数指的是,有着不同的 iii ,相同的 nnn 的一系列 {ni}\begin{Bmatrix}n\\i\end{Bmatrix}{ni​} 。求出同一行的所有第二类斯特林数,就是对 i=0⋯ni=0\cdots ni=0⋯n求出了将 nnn 个不同元素划分为 iii 个非空集的方案数。

int main() {scanf("%d", &n);fact[0] = 1;for (int i = 1; i <= n; ++i)fact[i] = 1ll * fact[i - 1] * i % mod;exgcd(fact[n], mod, ifact[n], ifact[0]),ifact[n] = (ifact[n] % mod + mod) % mod;for (int i = n - 1; i >= 0; --i)ifact[i] = 1ll * ifact[i + 1] * (i + 1) % mod;poly f(n + 1), g(n + 1);for (int i = 0; i <= n; ++i)g[i] = (i & 1 ? mod - 1ll : 1ll) * ifact[i] % mod,f[i] = 1ll * qpow(i, n) * ifact[i] % mod;f *= g;f.resize(n + 1);for (int i = 0; i <= n; ++i)printf("%d ", f[i]);return 0;
}

0x28 简单应用举例

  第二类斯特林数主要是用于解决组合数学中的几类放球模型。主要是针对于球之前有区别的放球模型:

(1) nnn 个不同的球,放入 m 个无区别的盒子,不允许盒子为空。

方案数:S(n,m)S\left(n,m\right)S(n,m) 。这个跟第二类斯特林数的定义一致。

(2) nnn 个不同的球,放入 mmm 个有区别的盒子,不允许盒子为空。

方案数:m!⋅S(n,m)m!\cdot S\left(n,m\right)m!⋅S(n,m) 。因盒子有区别,乘上盒子的排列即可。

(3)nnn 个不同的球,放入 mmm 个无区别的盒子,允许盒子为空。

方案数:∑k=0mS(n,k)\sum\limits_{k=0}^mS(n,k)k=0∑m​S(n,k) 。枚举非空盒的数目便可。

(4)nnn 个不同的球,放入 mmm 个有区别的盒子,允许盒子为空。

①方案数:∑k=0mP(m,k)⋅S(n,k)\sum\limits_{k=0}^mP(m,k)\cdot S(n,k)k=0∑m​P(m,k)⋅S(n,k)。同样可以枚举非空盒的数目,注意到盒子有区别,乘上一个排列系数。

②既然允许盒子为空,且盒子间有区别,那么对于每个球有m种选择,每个球相互独立。有方案数:mnm^nmn。

mn=∑k=0mP(m,k)⋅S(n,k)m^n=\sum_{k=0}^mP(m,k)\cdot S(n,k)mn=k=0∑m​P(m,k)⋅S(n,k)

上述式子可以应用于第二类斯特林数通项的求解。

0x29 竞赛例题选讲

待更…

0x30 第三类斯特林数

0x31 第三类斯特林数(拉赫数)定义

  拉赫数是由伊沃·拉赫在1954年发现的,因为拉赫数与斯特林数关系密切,所以有时拉赫数也被称为’’‘第三类斯特林数’’’。可以用升阶函数或降阶函数定义为:

xnˉ=∑k=0nL(n,k)xk‾x^{\bar n } = \sum\limits_{k=0}^n L(n,k) x^{\underline k}xnˉ=k=0∑n​L(n,k)xk​

xn‾=∑k=0n(−1)n−kL(n,k)xkˉx^{\underline n} = \sum\limits_{k=0}^n (-1)^{n-k} L(n,k) x^{\bar k }xn​=k=0∑n​(−1)n−kL(n,k)xkˉ

其中, L(n,k)L(n,k)L(n,k) 即为拉赫数。

例如:

x3ˉ=∑k=03L(3,k)xk‾x^{\bar 3}=\sum\limits_{k=0}^3 L(3,k) x^{\underline k}x3ˉ=k=0∑3​L(3,k)xk​

x(x+1)(x+2)=L(3,0)⋅1+L(3,1)⋅x+L(3,2)⋅x(x−1)+L(3,3)⋅x(x−1)(x−2)x(x+1)(x+2)=L(3,0)\cdot 1 + L(3,1)\cdot x + L(3,2)\cdot x(x-1) + L(3,3)\cdot x(x-1)(x-2)x(x+1)(x+2)=L(3,0)⋅1+L(3,1)⋅x+L(3,2)⋅x(x−1)+L(3,3)⋅x(x−1)(x−2)

等式两边展开并合并同类项,得

0⋅x0+2⋅x+3⋅x2+1⋅x3=L(3,0)+[L(3,1)−L(3,2)+2L(3,3)]⋅x+[L(3,2)−3L(3,3)]⋅x2+L(3,3)⋅x3\ \ \ \ \ 0\cdot x^0 + 2\cdot x+3\cdot x^2+1\cdot x^3\\=L(3,0)+[L(3,1)-L(3,2)+2L(3,3)]\cdot x+[L(3,2)-3L(3,3)]\cdot x^2 +L(3,3)\cdot x^3     0⋅x0+2⋅x+3⋅x2+1⋅x3=L(3,0)+[L(3,1)−L(3,2)+2L(3,3)]⋅x+[L(3,2)−3L(3,3)]⋅x2+L(3,3)⋅x3

比较等式两边系数,得

{L(3,0)=0L(3,1)−L(3,2)+2L(3,3)=2L(3,2)−3L(3,3)=3L(3,3)=1\begin{cases}{L(3,0)=0} \\ {L(3,1)-L(3,2)+2L(3,3)=2} \\ {L(3,2)-3L(3,3)=3} \\ {L(3,3)=1}\end{cases}⎩⎪⎪⎪⎨⎪⎪⎪⎧​L(3,0)=0L(3,1)−L(3,2)+2L(3,3)=2L(3,2)−3L(3,3)=3L(3,3)=1​

解得
L(3,0)=0L(3,0)=0L(3,0)=0 ,L(3,1)=6L(3,1)=6L(3,1)=6, L(3,2)=6L(3,2)=6L(3,2)=6 , L(3,3)=1L(3,3)=1L(3,3)=1 。

x3‾=∑k=03(−1)3−kL(3,k)x3ˉx^{\underline 3}=\sum\limits_{k=0}^3 (-1)^{3-k} L(3,k) x^{\bar 3}x3​=k=0∑3​(−1)3−kL(3,k)x3ˉ

x(x−1)(x−2)=L(3,0)⋅1+L(3,1)⋅x+L(3,2)⋅x(x+1)+L(3,3)⋅x(x+1)(x+2)\ \ \ \ x(x-1)(x-2)\\=L(3,0)\cdot 1 + L(3,1)\cdot x + L(3,2)\cdot x(x+1) + L(3,3)\cdot x(x+1)(x+2)    x(x−1)(x−2)=L(3,0)⋅1+L(3,1)⋅x+L(3,2)⋅x(x+1)+L(3,3)⋅x(x+1)(x+2)

等式两边展开并合并同类项,得

0⋅x0+2⋅x−3⋅x2+1⋅x3=−L(3,0)+[L(3,1)−L(3,2)+2L(3,3)]⋅x+[−L(3,2)+3L(3,3)]⋅x2+L(3,3)⋅x3\ \ \ \ \ 0\cdot x^0 + 2\cdot x-3\cdot x^2+1\cdot x^3\\=-L(3,0)+[L(3,1)-L(3,2)+2L(3,3)]\cdot x+[-L(3,2)+3L(3,3)]\cdot x^2 +L(3,3)\cdot x^3     0⋅x0+2⋅x−3⋅x2+1⋅x3=−L(3,0)+[L(3,1)−L(3,2)+2L(3,3)]⋅x+[−L(3,2)+3L(3,3)]⋅x2+L(3,3)⋅x3

比较等式两边系数,得

{L(3,0)=0L(3,1)−L(3,2)+2L(3,3)=2−L(3,2)+3L(3,3)=−3L(3,3)=1\begin{cases}{L(3,0)=0} \\ {L(3,1)-L(3,2)+2L(3,3)=2} \\ {-L(3,2)+3L(3,3)=-3} \\ {L(3,3)=1}\end{cases}⎩⎪⎪⎪⎨⎪⎪⎪⎧​L(3,0)=0L(3,1)−L(3,2)+2L(3,3)=2−L(3,2)+3L(3,3)=−3L(3,3)=1​

解得
L(3,0)=0L(3,0)=0L(3,0)=0 , L(3,1)=6L(3,1)=6L(3,1)=6 , L(3,2)=6L(3,2)=6L(3,2)=6 , L(3,3)=1L(3,3)=1L(3,3)=1 。


  以上定义的拉赫数是无符号拉赫数(signed Lah numbers),有符号拉赫数(signed Lah numbers)的定义如下:

xnˉ=(−1)n∑k=0nL(n,k)xk‾x^{\bar n} = (-1)^n \sum_{k=0}^n L(n,k)x^{\underline k}xnˉ=(−1)nk=0∑n​L(n,k)xk​

xn‾=∑k=0n(−1)kL(n,k)xkˉx^{\underline n}= \sum_{k=0}^n (-1)^k L(n,k) x^{\bar k}xn​=k=0∑n​(−1)kL(n,k)xkˉ

  无符号拉赫数计算的是将含有 nnn 个元素的集合拆分为 kkk 个非空线性有序子集的方法数目 。例如:对于集合 {(1,2,3)}\left\{(1,2,3)\right\}{(1,2,3)} ,若拆分为 000 个非空线性有序子集,显然有零种方法;拆分为 111 , 个非空线性有序子集,有 {(1,2,3)}\left\{(1, 2, 3)\right\}{(1,2,3)} , , {(1,3,2)}\left\{(1, 3, 2)\right\}{(1,3,2)} , {(2,1,3)}\left\{(2, 1, 3)\right\}{(2,1,3)} , {(2,3,1)}\left\{(2, 3, 1)\right\}{(2,3,1)} , {(3,1,2)}\left\{(3, 1, 2)\right\}{(3,1,2)} , {(3,2,1)}\left\{(3, 2, 1)\right\}{(3,2,1)} 六种方法。拆分为 222 个非空线性有序子集,有 {(1)}\left\{(1)\right\}{(1)} {(2,3)}\left\{(2, 3)\right\}{(2,3)}, {(1)}\left\{(1)\right\}{(1)} {(3,2)}\left\{(3, 2)\right\}{(3,2)}, {(2)}\left\{(2)\right\}{(2)} {(1,3)}\left\{(1, 3)\right\}{(1,3)} , {(2)}\left\{(2)\right\}{(2)} {(3,1)}\left\{(3, 1)\right\}{(3,1)}, {(3)}\left\{(3)\right\}{(3)} {(1,2)}\left\{(1, 2)\right\}{(1,2)}, {(3)}\left\{(3)\right\}{(3)} {(2,1)}\left\{(2, 1)\right\}{(2,1)} 六种方法。拆分为 333 个非空线性有序子集,有 {(1)}\left\{(1)\right\}{(1)} , {(2)}\left\{(2)\right\}{(2)} , {(3)}\left\{(3)\right\}{(3)} 一种方法。于是 L(3,0)=0L(3,0)=0L(3,0)=0 , L(3,1)=6L(3,1)=6L(3,1)=6 , L(3,2)=6L(3,2)=6L(3,2)=6 , L(3,3)=1L(3,3)=1L(3,3)=1 。

无符号拉赫数可以使用以下公式进行计算:

L(n,k)=(n−1k−1)n!k!L(n,k) = {n-1 \choose k-1} \cfrac{n!}{k!}L(n,k)=(k−1n−1​)k!n!​

有符号拉赫数可以使用以下公式进行计算:

L′(n,k)=(−1)n(n−1k−1)n!k!L'(n,k) = (-1)^n {n-1 \choose k-1} \cfrac{n!}{k!}L′(n,k)=(−1)n(k−1n−1​)k!n!​

0x32 递推求第三类斯特林数

无符号拉赫数有如下递推关系:

L(n,k+1)=n−kk(k+1)L(n,k)L(n,k+1) = \cfrac{n-k}{k(k+1)} L(n,k)L(n,k+1)=k(k+1)n−k​L(n,k)

或者:

L(n+1,k)=(n+k)L(n,k)+L(n,k−1)L(n+1,k) = (n+k) L(n,k) + L(n,k-1)L(n+1,k)=(n+k)L(n,k)+L(n,k−1)

边界条件:

L(n,0)=0L(n,0)=0L(n,0)=0

L(n,0)=0L(n,0)=0L(n,0)=0

L(n,k)=0L(n,k)=0L(n,k)=0 ( k>nk>nk>n )

L(1,1)=1L(1,1)=1L(1,1)=1

0x33 第三类斯特林数表

无符号拉赫数表

n \ k 0 1 2 3 4 5 6
0 1
1 0 1
2 0 2 1
3 0 6 6 1
4 0 24 36 12 1
5 0 120 240 120 20 1
6 0 720 1800 1200 300 30 1

0x34 第三类斯特林数的性质

第三类斯特林数(拉赫数)的简单性质

性质34.1: L(0,0)=1L(0,0)=1L(0,0)=1 , L(n,0)=0L(n,0)=0L(n,0)=0 ( n>0n>0n>0 )

性质34.2: 如果 k>nk>nk>n ,有 L(0,0)=1L(0,0)=1L(0,0)=1 , L(n,k)=0L(n, k)=0L(n,k)=0

性质34.3: L(n,1)=n!L(n,1) = n!L(n,1)=n!

性质34.4: L(n,2)=(n−1)n!2L(n,2) = \frac{(n-1)n!}{2}L(n,2)=2(n−1)n!​

性质34.5: L(n,3)=(n−2)(n−1)n!12L(n,3) = \frac{(n-2)(n-1)n!}{12}L(n,3)=12(n−2)(n−1)n!​

性质34.6: L(n,n−1)=n(n−1)L(n,n-1) = n(n-1)L(n,n−1)=n(n−1)

性质34.7: L(n,n)=1L(n,n) = 1L(n,n)=1

性质34.8: ∑n≥kL(n,k)xnn!=1k!(x1−x)k\sum_{n\geq k}L(n,k)\frac{x^n}{n!}= \frac{1}{k!}\left( \frac{x}{1-x} \right)^k∑n≥k​L(n,k)n!xn​=k!1​(1−xx​)k

无符号拉赫数计算公式可以作进一步拓展:

L(n,k)=(n−1k−1)n!k!=(nk)(n−1)!(k−1)!=(nk)(n−1k−1)(n−k)!L(n,k) = {n-1 \choose k-1} \cfrac{n!}{k!} = {n \choose k} \cfrac{(n-1)!}{(k-1)!} = {n \choose k} {n-1 \choose k-1} (n-k)!L(n,k)=(k−1n−1​)k!n!​=(kn​)(k−1)!(n−1)!​=(kn​)(k−1n−1​)(n−k)!

L(n,k)=n!(n−1)!k!(k−1)!⋅1(n−k)!=(n!k!)2kn(n−k)!L(n,k) = \cfrac{n!(n-1)!}{k!(k-1)!}\cdot\cfrac{1}{(n-k)!} = \left (\cfrac{n!}{k!} \right )^2\cfrac{k}{n(n-k)!}L(n,k)=k!(k−1)!n!(n−1)!​⋅(n−k)!1​=(k!n!​)2n(n−k)!k​


上述性质的证明,有缘再写

0x40 三类斯特林数之间的转换

两类斯特林数之间的递推式和实际含义很类似,他们之间存在一个互为转置的转化关系:

∑k=0nS1(n,k)S2(k,m)=∑k=0nS2(n,k)S1(k,m)\sum_{k=0}^nS1(n,k)S2(k,m)=\sum_{k=0}^nS2(n,k)S1(k,m)k=0∑n​S1(n,k)S2(k,m)=k=0∑n​S2(n,k)S1(k,m)

三类斯特林数以及乘方、阶乘之间的关系可以用 图40.1 表示

图40.1

无符号拉赫数与两类斯特林数都有关系 ,关系如下:

L(n,k)=∑j=0n[nj]{jk}L(n,k)=\sum\limits_{j=0}^n \left[\begin{matrix} n \\ j \end{matrix}\right] \left\{\begin{matrix} j \\ k \end{matrix}\right\}L(n,k)=j=0∑n​[nj​]{jk​}

由无符号拉赫数与两类斯特林数之间的关系,考虑到两类斯特林数之间的关系,有

∑j≥0L(n,j)L(j,k)=δnk\sum _{j\geq 0}L(n,j)L(j,k)=\delta _{nk}∑j≥0​L(n,j)L(j,k)=δnk​

其中, δnk\delta_{nk}δnk​ 是 克罗内克尔δ

0x50 斯特林反演

0x51 前置知识

这里先复习一下两类斯特林数与上升幂,下降幂之间的转换公式:

xn=∑i=0nS(n,i)xi‾xn=∑i=0n(−1)n−iS(n,i)xi‾xn‾=∑i=0n(−1)n−is(n,i)xixn‾=∑i=0ns(n,i)xi\begin{aligned} x^n&=\sum_{i=0}^{n}S(n,i)x^{\underline i}\\ x^n&=\sum_{i=0}^{n}(-1)^{n-i}S(n,i)x^{\overline i}\\ x^{\underline n}&=\sum_{i=0}^{n}(-1)^{n-i}s (n,i)x^i\\ x^{\overline n}&=\sum_{i=0}^{n}s (n,i)x^i \end{aligned}xnxnxn​xn​=i=0∑n​S(n,i)xi​=i=0∑n​(−1)n−iS(n,i)xi=i=0∑n​(−1)n−is(n,i)xi=i=0∑n​s(n,i)xi​

根据下降幂的公式:

xn=∑i=0nS(n,i)xi‾x^n=\sum_{i=0}^{n}S(n,i)x^{\underline i}xn=i=0∑n​S(n,i)xi​

我们根据上面的公式将其变成上升幂:

xn=∑i=0nS(n,i)(−1)i(−x)i‾x^n=\sum_{i=0}^{n}S(n,i)(-1)^i(-x)^{\overline i}xn=i=0∑n​S(n,i)(−1)i(−x)i

代入上升幂转第一类斯特林数的公式:

xn=∑i=0nS(n,i)(−1)i∑j=0is(i,j)(−x)jx^n=\sum\limits_{i=0}^{n}S(n,i)(-1)^i\sum\limits_{j=0}^{i}s(i,j)(-x)^jxn=i=0∑n​S(n,i)(−1)ij=0∑i​s(i,j)(−x)j

把 xxx 的幂提前,换一下求和符号:

xn=∑j=0nxj∑i=jnS(n,i)s(i,j)(−1)i−jx^n=\sum\limits_{j=0}^{n}x^j\sum\limits_{i=j}^nS(n,i)s(i,j)(-1)^{i-j}xn=j=0∑n​xji=j∑n​S(n,i)s(i,j)(−1)i−j

由于这里我们把 xxx 看成未知量,其他的都是已知量,所以我们可以把左右当作多项式,那么对比系数可得 反转公式

∑i=mnS(n,i)s(i,m)(−1)i−m=[m=n]\sum\limits_{i=m}^{n}S(n,i)s(i,m)(-1)^{i-m}=[m=n]i=m∑n​S(n,i)s(i,m)(−1)i−m=[m=n]

同理我们可以得出第二个反转公式

∑i=mns(n,i)S(i,m)(−1)i−m=[m=n]\sum\limits_{i=m}^{n}s(n,i)S(i,m)(-1)^{i-m}=[m=n]i=m∑n​s(n,i)S(i,m)(−1)i−m=[m=n]

注意:反转公式 −1−1−1 的指数也可以写成 n−in−in−i ,稍加分析可以发现 m=nm=nm=n 时成立, m≠nm≠nm​=n 时有两种情况,一种不变,另一种会将答案取相反数,但是由于结果为 000 所以不影响。

0x52 斯特林反演及其证明

了解了上面的前置知识以后,我们引出斯特林反演的公式

f(n)=∑i=0nS(n,i)g(i)⟺g(n)=∑i=0n(−1)n−is(n,i)f(i)f(n)=\sum_{i=0}^{n}S(n,i)g(i)\Longleftrightarrow g(n)=\sum_{i=0}^{n}(-1)^{n-i}s(n,i)f(i)f(n)=i=0∑n​S(n,i)g(i)⟺g(n)=i=0∑n​(−1)n−is(n,i)f(i)

考虑证明:


我们先写出一个 [i=n][i=n][i=n] 的形式:

g(n)=∑i=0n[i=n]g(i)g(n)=\sum\limits_{i=0}^{n}[i=n]g(i)g(n)=i=0∑n​[i=n]g(i)

我们再把斯特林数以及 [m=n][m=n][m=n] 的式子套进去,也就是上面的反转公式(注意 −1−1−1 的指数):

g(n)=∑i=0ng(i)∑j=in(−1)n−js1(n,j)s2(j,i)=∑j=0n(−1)n−js1(n,j)∑i=0js2(j,i)g(i)=∑i=0n(−1)n−is1(n,i)f(i)\begin{aligned} g(n)&=\sum_{i=0}^{n}g(i)\sum_{j=i}^{n}(-1)^{n-j}s_1(n,j)s_2(j,i)\\ &=\sum_{j=0}^{n}(-1)^{n-j}s_1(n,j)\sum_{i=0}^{j}s_2(j,i)g(i)\\ &=\sum_{i=0}^{n}(-1)^{n-i}s_1(n,i)f(i) \end{aligned}g(n)​=i=0∑n​g(i)j=i∑n​(−1)n−js1​(n,j)s2​(j,i)=j=0∑n​(−1)n−js1​(n,j)i=0∑j​s2​(j,i)g(i)=i=0∑n​(−1)n−is1​(n,i)f(i)​

综上所述,斯特林反演公式得证。□

当然由于反转公式的对称性,所以互换 sss 和 SSS 依然成立。

0x53 竞赛例题选讲

待更…


参考资料:

  • 《组合数学》原书第五版
  • 维基百科
  • 百度百科
  • oiwiki
  • 斯特林数入门
  • 组合数学 —— 斯特林数(Stirling)
  • 第二类斯特灵数学习笔记

《小学生都能看懂的三类斯特林数从入门到升天教程 》(含性质完整证明、斯特林反演、拉赫数)相关推荐

  1. 《小学生都能看懂的快速沃尔什变换从入门到升天教程》(FWT / FMT / FMI)(最最严谨清晰的证明!零基础也能得学会!)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 0x00 卷积 0x01 多项式 0x02 卷积的定义 0x03 卷积的基本性质 0x04 位运 ...

  2. 小学生都能看懂的FFT!!!

    小学生都能看懂的FFT!!! 前言 在创新实践中心偷偷看了一天FFT资料后,我终于看懂了一点.为了给大家提供一份简单易懂的学习资料,同时也方便自己以后复习,我决定动手写这份学习笔记. 食用指南: 本篇 ...

  3. 小学生都能看懂,彻底解决环境搭建难题,一步一截图,再无VMware网络难题

    小学生都能看懂,彻底解决环境搭建难题,一步一截图,再无VMware网络难题 原创 韦东山 百问科技 1周前 上周四我们预告了这周要发布环境搭建的终极解决方案,经过一周的努力,终于写好了文档,Ubunt ...

  4. 《小学生都能看懂的生成函数从入门到升天教程》《生成函数全家桶》

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 小学生都能看懂系列 目录 0x00 生成函数 0x10 例题引入 0x11 ExampleA\tt E ...

  5. 《小学生都能看懂的群论从入门到升天教程》 《群论全家桶》

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 小学生都能看懂系列,小学生:我太难了   群论.置换.Bunrnside引理.Pόlya定理等概念是群 ...

  6. nxn次方求和函数_算法|小学生都能看懂的生成函数入门教程

    作者:自为风月马前卒 链接:https://ac.nowcoder.com/discuss/179728 来源:牛客网 前言 第一次当标题党真是有点不适应 现在网上讲生成函数的教程大多都是从 开始,但 ...

  7. TCP 的 3 次握手 4 次挥手,小学生都能看懂

    前几天发了一个朋友圈,发现暗恋已久的女生给我点了个赞,于是我当晚辗转反侧.彻夜未眠!想着妹子是不是对我有感觉呢?不然怎么会突然给我点赞呢?要不趁机表个白? 于是第二天我在心中模拟了多次表白的话语,连呼 ...

  8. 大白话解释:到底什么是人工智能(AI),小学生都能看懂

    现在人工智能(AI)一词满天飞,上到国家和地方ZF的科技创新扶持政策,下到大小公司的各种智能XXX.智慧XXX产品或解决方案,似乎不加上人工智能,就显得没有技术含量.不够高端.反正人工智能一词有点泛滥 ...

  9. 什么是分布式数据库?小学生都能看懂。

    自从互联网进入了 web2.0 时代以来,数据库作为核心的底层基础设施软件也经历了蓬勃的发展期,从早期的单机关系型数据库到NoSQL 再到如今的 NewSQL,数据库领域不管是技术还是场景都发生了巨大 ...

最新文章

  1. iOS封装HTTPS双向和单向验证
  2. 华人“霸榜”ACL最佳长短论文、杰出论文一作,华为、南理工等获奖
  3. python使用函数的目的_在Python 3.x中经常看到定义函数有一个单独的 * 参数?定义这样参数的目的是?怎样对其取值呢?...
  4. websocket(二):SSM+websocket的聊天室
  5. 动态可订制属性的 PropertyGrid(转载)
  6. 【Android 应用开发】Android之Bluetooth编程
  7. 【JavaSE_06】Java中的数组(array)
  8. 报录比2比1计算机学校,比报录比更值得关注的,是推免率!内含20考研985院校推免数据...
  9. (含Python源码)Python实现K阶多项式的5种回归算法(regression)
  10. 【文章】一副对联,便写尽了人生
  11. jeecg怎么样好用吗?
  12. Dubbo源码分析(三):ExtensionLoader
  13. Delphi XE 10.2.3使用FastReport 6.0.7
  14. 中国移动何时成为“移动信息专家”
  15. Blender 合成节点 中英文对照
  16. 658.一元二次方程公式
  17. Android8怎么格式化内存卡,安卓手机怎么格式化存储内存 Android手机SD内存卡格式化方法...
  18. 人工智能发展史(读书笔记)
  19. c语言画实心坐标点,c-绘制实心圆的快速算法?
  20. 保存rdl文件到报表服务器,在SQL服务器上将RDL报表导出成Excel XLS XLSX SpreadsheetML格式...

热门文章

  1. 站长在线Python精讲:Python中字符串编码转换encode编码和decode解码详解
  2. 墨水屏可视化超高频电子标签技术优势与应用解决方案
  3. 对话庄表伟老师-文字实录
  4. C++课程设计实训_基于多态书籍信息管理系统的设计与实现、附源码、有过程截图
  5. Django学习——基础篇(上)
  6. AJAX file uploads in Rails using attachment_fu and responds_to_parent 1
  7. 关于如何不使用黄钻或绿钻永久添加背景音乐的问题
  8. 推荐模型复现(四):多任务模型ESMM、MMOE
  9. error LNK1104: 无法打开文件“kernel32.lib”错误 Visual Studio 2017解决办法
  10. Jena 简介:通过 Jena Semantic Web Framework 在 Jave 应用程序中使用 RDF 模型