排列组合基础 (Basics)
排列 (Permutation)
从 个不同元素中取出 个元素排成一列,称为排列,记作 或 :
特殊情况:当 时,
组合 (Combination)
从 个不同元素中取出 个元素成一组(不考虑顺序),称为组合,记作 或 :
重要性质:(对称性)
组合数的性质
组合数满足递推关系(Pascal’s triangle / 杨辉三角):
由此可得:
二项式定理 (Binomial Theorem)
推论
- 令 :
- 令 :
常用计数技巧 (Common Counting Techniques)
加法原理与乘法原理
加法原理:完成一件事有 类方式,第 类方式有 种方法,则总方法数为:
乘法原理:完成一件事需要 个步骤,第 步有 种方法,则总方法数为:
容斥原理 (Inclusion-Exclusion Principle)
用于计算若干集合的并集大小。设 为有限集合,则:
简单例子(三个集合):
抽屉原理 (Pigeonhole Principle)
简单形式:如果把 个物体放入 个盒子,则至少有一个盒子中有两个或更多物体。
广义形式:如果把 个物体放入 个盒子,则至少有一个盒子中含有至少 个物体。
应用示例:在 个整数中,必有两个整数的差是 的倍数。
递推关系 (Recurrence Relations)
斐波那契数列 (Fibonacci Sequence)
前几项:
通项公式(Binet公式):
其中 ,
Catalan 数
Catalan 数 满足:
前几项:
组合意义:
- 含有 个叶子的满二叉树的个数
- 对括号的有效匹配数
- 棋盘从左下角到右上角不穿过对角线的路径数
Stirling 数
第一类 Stirling 数 :将 个元素分成 个非空循环排列的方法数。
递推公式:
第二类 Stirling 数 :将 个元素分成 个非空集合的方法数。
递推公式:
母函数初步 (Generating Function Basics)
母函数(生成函数)用于解决递推关系和计数问题。
普通母函数
序列 的普通母函数为:
示例:对于 Fibonacci 数列,母函数为:
指数母函数
序列 的指数母函数为:
经典应用
用母函数可以证明组合恒等式,例如:
组合数取模 (Modular Combinatorics)
Lucas 定理
当 为素数时,组合数取模可以用 Lucas 定理高效计算:
其中 , 是 进制表示。
适用场景: 很大(甚至达到 ),但 较小(如 )。
预处理阶乘与逆阶乘
在模 下计算组合数,通常需要预计算阶乘和逆阶乘:
const int MOD = 1e9 + 7;
const int MAXN = 2e6 + 5;
int64_t fact[MAXN], infact[MAXN];
int64_t mod_pow(int64_t a, int64_t b) {
int64_t res = 1;
while (b) {
if (b & 1) res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
void init_factorials(int n) {
fact[0] = 1;
for (int i = 1; i <= n; i++) {
fact[i] = fact[i-1] * i % MOD;
}
infact[n] = mod_pow(fact[n], MOD - 2); // Fermat's little theorem
for (int i = n; i > 0; i--) {
infact[i-1] = infact[i] * i % MOD;
}
}
int64_t C(int n, int m) {
if (n < 0 || m < 0 || m > n) return 0;
return fact[n] * infact[m] % MOD * infact[n-m] % MOD;
}注意:
- 当 为素数时,(Fermat 小定理)
- 使用 Lucas 定理时,递归计算即可