计数总结
巨长还没人看的笔记第二弹。
本文md源码全长超过25KB/900行,除非有时间并不建议完整阅读而是通过Ctrl+F查找想阅读的部分
建议在食用前熟读本博客的数论总结一文中的同余部分。
排列与组合
加法原理与乘法原理
加法原理:假设我们要做一件事情,有
乘法原理:假设我们要做一件事情,有
排列与组合
排列数
有
可以轻易地推导排列的计算公式:
理解:取第
组合数
在
组合数的公式也很容易推导。
理解:我们选择的
一般而言我们都不使用排列而是使用组合,因为组合转排列只需要乘而排列转阶乘需要除,在取模横行的 OI 界相当不友好;并且大部分题目要求的也是组合数。
特别的,当
多重集的排列数/多重组合数
考虑一个多重集有
则此多重集的全排列数/多重组合数为:
记作
理解:
- 我们并不关心相同种类的元素的顺序,因此每一种都要除以
。 - 可以理解为:有
个球,第 次选取其中没有选过的 个球涂色,求最终方案数,答案即为
插板法
插板法一般用于求解元素划分问题,核心思想是考虑待求式的组合意义。
解:我们考虑方程的解数相当于下面这个情景:
有
个球排成一排,你可以在任意两个球的空隙种插入板以把左右两边分开,一个空隙只能插一块板,求插 块板方案数。
那么答案显然是
看起来这个情景中没法插板了,因为一个空隙能插很多块板。
但是我们可以考虑变形:
这样就可以插板了。答案
杨辉三角
懒得做图了。直接贺亿张 Wikipedia 的图。
上图即为杨辉三角,从第二行开始其每一个值都是其左上方和有右上方数的和(不存在即为
杨辉三角的性质:在左对齐后,第
由此我们可以得出组合数的递推式:
这个公式也可以用组合意义理解:我们要考虑第
严格的 proof 可以展开组合数。
此外我们还可以观察到:第
二项式定理
proof可以用归纳。
理解:考虑组合意义,相当于在
组合数的重要性质
下面这些式子基本上写作阶乘之后都一目了然,因此不再给出证明。
这些式子非常重要,大部分计数题基本上都只用得上这些,剩下的式子基本上都可以从这些推导出来,因此务必要熟悉。
对称式
理解:选
吸收式
或
我们也可以使下指标不变:
这个式子的意义在于可以将系数移入或移出组合数。
上指标求和(同列求和)
理解:从
组合数“约分”/三项式系数
前一个名字是我乱取的,主要真的很像约分啊。
理解:左式相当于在
下指标卷积(范德蒙德卷积)
理解:在
变形:
上指标卷积
组合数的常用推导方式
- 组合意义:把抽象的组合式转化成等价的计数模型,再寻找这个计数模型的性质。
- 优点:理解直观,可能可以更快地发现一些关键性质
- 缺点:对思维要求较高,泛用性不强。
- 拆解组合数:把组合数拆解为阶乘式,可以在分子分母上同时乘一些其他的式子,并重新组合新的组合数。
- 优点:较为泛用,在不能用组合意义的时候有用;对思维要求没有组合意义高。
- 缺点:对计算能力和数学直觉要求高。
组合数的编程求法
根据题目要求,有以下几种求组合数的方法:
本文内容不包括exLucas,建议出模数不是质数数据范围还大的出题人干点人事
递推
直接使用递推式计算组合数。
1 | const int M=1000; |
时间复杂度:
优点:代码简单,对模数没有要求,在需要大量查询的时候常数最小
缺点:只能处理
适用范围:
预处理+阶乘式
当需要取模且模数为质数时,可以预处理
1 | const int P=1e9+7; |
优化
ちょっと待って,这份代码是
会,因此我们可以考虑一个性质:
根据阶乘的定义即可证明。
因此我们就得到了一个递推式。我们只需要计算出
1 | void pre(){ |
时间复杂度:
优点:可以处理较大范围,代码简单
缺点:只能在模数为质数时使用
适用范围:
卢卡斯定理
有时我们会遇到
定理内容
由于这个式子还能递归,因此我们也可以换一种方式:
设
proof
引理1:
proof:
引理2:
proof:我们考虑使用二项式定理:
我们观察右半边的第三项,其中包含
我们接下来证明
然后就可以开始归纳了。
我们现在正式开始证明。
我们设
根据二项式定理,
根据引理2有
我们已知
而我们又有
因此我们抽出第
消掉
证毕。
拓展
对于
时间复杂度:
优点:可以求解很大的
缺点:只能在模数为质数时使用不适用
适用范围:
质因数分解
前置知识:阶乘的质因数分解
我们直接对
时间复杂度:单次
优点:对模数没有要求,处理数据范围较大
缺点:多次查询复杂度高
适用范围:查询次数较少,
卷积快速幂
我们考虑下面这个下指标卷积:
于是我们可以设计一个快速计算
时间复杂度:可用狒狒贴优化到
适用范围:
总结一下:
算法 | ||||
---|---|---|---|---|
递推 | 小 | 大 | 无 | 大 |
预处理阶乘 | 中 | 大 | 大 | |
卢卡斯定理 | 大 | 中 | 大 | |
质因数分解 | 中 | 大 | 无 | 小 |
卷积快速幂 | 大 | 无 | 小 | |
容斥原理
引入
一个班上有
用数学的语言来讲,设
直观理解:
子集容斥
三个集合的情况:
推广到
proof:我们考虑必须选择第
因此每个元素只被算了一次。
容斥原理的常用套路是把“至少”、“至多”与“恰好”互化,这样就可以用一些交集算并集或用并集算交集。
例子
求解下列方程的自然数解组数:
我们考虑
我们考虑枚举每个
直接算即可。
二项式反演
证明直接暴力展开即可。
...所以这玩意是拿来干嘛的啊?
在做题的时候我们常常要计算“恰好满足”,但是“恰好满足”常常不好计算,而“至少满足”或“至多满足”反而更好计算。
此时我们可以用二项式反演。式子中
这样我们就可以用“至少”与“恰好”互推了。
类似的,我们也可以用“至多”与“恰好”互推:
事实上二项式反演的本质也是容斥。下文不会特别区分“子集容斥”与二项式反演。
特殊的数
在 OI 中经常会遇到一些模型,这些模型往往都对应一种特殊的数且具有高度的类似性,掌握这些数的性质往往会对快速解题有帮助。
错排
定义一个排列
求长为
容斥计算
我们可以轻易地用子集容斥计算:定义
所以答案即为
递推计算
我们考虑一个错排的具体问题:
考虑递推计算。我们假设已经把编号为
- 如果前面的钥匙全部不配对,那么随意选择一个钥匙与编号为
的钥匙交换即可。这种情况会出现 次,而交换方案数为 种。 - 如果前面恰好有一把钥匙与锁配对,那么我们就可以把这两个钥匙交换就得到了错排。这种情况会出现
次,而交换方案数为 种。
综上我们得到了错排数递推式:
卡特兰数
卡特兰数(Catalan Number)的组合数形式与递推式如下:
其中
卡特兰数可能是 OI 中对应模型最多的特殊数了。下面这些都是卡特兰数的组合意义:
- 从
出发走到 ,每次只能向上或向右,可以碰到但是不能穿过对角线 ,合法路径的条数。 - 长为
的合法括号序列数。 依次进栈,合法的出栈序列数。- 在圆上均匀选取
个等距的点连 条弦,这些弦互不相交的方案数。 个结点的二叉树的数量。 个结点的森林或 个结点的树的数量。- 凸
边形的三角剖分方案数。 - 用边长为整数的矩形水平或竖直放置填满一个高为
的楼梯的方案数(详见 AHOI2012 树屋阶梯)。
我们以第一个为例浅证一下。
先转化为“不能碰到
我们发现对于每一条碰到
这样每一种要碰到
由于
斯特林数
第二类斯特林数
第二类斯特林数(Stirling Number)的组合意义:把
我们可以根据组合意义写出递推式:我们考虑怎么转移到一个合法的把
- 我们把第
个球单独放进某个盒子,转移到 。 - 我们把第
个球放进之前的某个盒子,转移到 ,系数为 。
因此递推式为
边界
我们接下来考虑推导通项公式。
我们发现“不能有空盒”不太好计算,考虑容斥。
先把盒子暂时标号,设
因此
贝尔数
贝尔数(Bell Number):把
容易发现贝尔数就是同行斯特林数的和,即
我们考虑推导一个贝尔数的递推形式。
不难发现,我们只要枚举有多少元素和第
因此
第一类斯特林数
第一类斯特林数的组合意义:把
同样考虑递推:对于已有的
- 把第
个元素新开一个圆排列。转移到 。 - 把第
个元素放到之前的排列里。转移到 ,系数为 (注意不是 ,我们枚举的是把它放在哪个元素的后面)。
因此
边界
第一类斯特林数没有通项公式。
上升幂与下降幂
我们定义
容易发现
斯特林数与上升幂&下降幂
斯特林数是用于沟通普通幂与升降幂的桥梁。
上升幂转化为普通幂:
下降幂转化为普通幂:
普通幂转化为上升幂:
普通幂转化为下降幂:
欧拉数
欧拉数(Eulerian Number,不要和数论的
比如
我们还是先考虑递推。
我们考虑
- 原先有
个上升位置。 - 在排列的右端放一个
。转移到 。
- 在排列的右端放一个
- 在排列某个下降的位置插入一个
。转移到 ,系数为 。
- 在排列某个下降的位置插入一个
- 原先有
个上升位置。 - 在排列的左端放一个
。转移到 。
- 在排列的左端放一个
- 在排列某个上升的位置插入一个
。转移到 ,系数为 。
- 在排列某个上升的位置插入一个
综上:
那这个东西有通项公式吗?
有,是这个:
推导请参考final_trump的博客-Eulerian Number 组合推法。
十二重计数
十二重计数(Twelvefold Way)是指十二个计数问题,其都有下列形式:
- 你要把
个球放进 个盒子里,有多少种方案?
我们有三个条件可以选:球是否标号(Label/Unlabel),盒子是否标号,特殊限制:
- A:无限制
- B:每个盒子最少一个球
- C:每个盒子最多一个球
我们用三个字母描述一个问题,比如 LUB 就是球标号、盒子不标号、每个盒子最少一个球。
我们一个一个来解决。
LLA
球和盒子都标号,无特殊限制。
每个球都可以选
LLB
球和盒子都标号,每个盒子最少一个球。
第二类斯特林数,然后再乘盒子排列数,答案
LLC
球和盒子都标号,每个盒子最多一个球。
考虑选
LUA
球标号盒子不标号,无特殊限制。
枚举多少个盒子放球,答案即为第二类斯特林数的和:
如果
LUB
球标号盒子不标号,每个盒子最少一个球。
第二类斯特林数的组合意义,答案为
ULA
球不标号盒子标号,无特殊限制。
辅助元素插板即可。答案
ULB
球不标号盒子标号,每个盒子最少一个球。
直接插板即可。答案
ULC
球不标号盒子标号,每个盒子最多一个球。
也就是选
UUB
球和盒子都不标号,每个盒子最少一个球。
我么考虑
乍一看没有什么好的 DP 方法,但是这里有一个非常玄学的 DP:
边界
我们用刷表考虑它的组合意义:
- 加一个新的空盒子,转移到
。 - 给每个盒子都放一个球。转移到
。
这样可以保证先加入的盒子一定不比后加入的盒子放的球少。
这个
UUA
球和盒子都不标号,无特殊限制。
有两种方法:
- 枚举有几个空盒。答案即为
。 - 我们加
个球然后强制在每个盒子至少一个球,答案即为 。
因此
最后再来点好笑的。
UUC
球和盒子都不标号,每个盒子最多一个球。
你是否清醒?
答案
LUC
球标号盒子不标号,每个盒子最多一个球。
你在搞笑吗?
答案
总结
组合数学虽然繁杂且看起来需要背很多东西,但是其最核心的部分还是阶乘、组合意义、容斥原理,并不需要刻意的去背。
组合数学尤其需要大量练题,尤其是容斥原理与二项式反演需要反复练习以掌握其技巧。
部分参考资料
- 《具体数学》,Graham、Knuth、Patashnik著
- OI-Wiki