algo15 数论与组合数学
模运算、素数筛、快速幂、最大公约数、组合数取模——算法竞赛中的数学工具箱
一、模运算(Modular Arithmetic)
1.1 基本运算
在模
除法需要特殊处理——用模逆元代替除法。
1.2 模逆元(Modular Inverse)
三种求法:
| 方法 | 条件 | 复杂度 |
|---|---|---|
| 费马小定理 | ||
| 扩展欧几里得 | 任意 | |
| 线性递推 | 批量求 |
费马小定理(
证明:
1.3 中国剩余定理(CRT)
对于一组同余方程组:
其中
其中
二、快速幂与矩阵快速幂
2.1 二进制快速幂(Binary Exponentiation)
计算
python
def fast_pow(x, n, mod):
result = 1
while n > 0:
if n & 1: # 当前二进制位为 1
result = result * x % mod
x = x * x % mod # 平方
n >>= 1 # 右移一位
return result原理:将指数
2.2 矩阵快速幂
快速幂的思想可以推广到矩阵。矩阵乘法的结合律使得
经典应用:斐波那契数列第
三、素数筛法
3.1 埃拉托色尼筛(Sieve of Eratosthenes)
筛选出
python
def sieve(n):
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(n ** 0.5) + 1):
if is_prime[i]:
for j in range(i * i, n + 1, i): # 从 i*i 开始,更小的已被筛过
is_prime[j] = False
return [i for i in range(n + 1) if is_prime[i]]复杂度:
3.2 欧拉线性筛(Euler's Linear Sieve)
保证每个合数只被其最小质因子筛掉一次,达到
python
def linear_sieve(n):
primes = []
is_prime = [True] * (n + 1)
for i in range(2, n + 1):
if is_prime[i]:
primes.append(i)
for p in primes:
if i * p > n: break
is_prime[i * p] = False
if i % p == 0: break # 关键:保证每个合数只被最小质因子筛掉
return primes关键行 if i % p == 0: break:当
四、最大公约数与扩展欧几里得
4.1 欧几里得算法(辗转相除法)
python
def gcd(a, b):
while b:
a, b = b, a % b
return a复杂度:
4.2 扩展欧几里得算法
求解
python
def ext_gcd(a, b):
if b == 0:
return a, 1, 0 # gcd, x, y
g, x1, y1 = ext_gcd(b, a % b)
x = y1
y = x1 - (a // b) * y1
return g, x, y应用:求模逆元——解
五、组合数学基础
5.1 排列与组合
- 排列
:有序选取 个 - 组合
:无序选取 个
5.2 二项式系数计算
方法一:递推(Pascal's Triangle)
适用于
方法二:组合数公式 + 模逆元
预处理阶乘和逆阶乘,
5.3 容斥原理
经典应用:
- 1 到
中与 互质的数的个数 - 错位排列(Derangements)
5.4 错位排列
递推:

六、概率基础
6.1 期望的线性性
线性性质:对于任意随机变量
这是概率论中最强大也最常用的性质之一。它允许将复杂期望分解为简单期望的和。
经典应用:掷
本章总结
| 概念 | 公式/方法 | 复杂度 |
|---|---|---|
| 模运算 | 加减乘直接取模 | |
| 模逆元(费马) | ||
| 中国剩余定理 | ||
| 快速幂 | 二进制分解 | |
| 埃筛 | 标记倍数 | |
| 线性筛 | 最小质因子 | |
| 欧几里得 | ||
| 扩展欧几里得 | ||
| 组合数 | 阶乘+逆元 或 Pascal 递推 | |
| 容斥原理 | 交集和并集转换 | 取决于项数 |
| 期望线性性 | — |
📥 Code
| File | View | Download |
|---|---|---|
| demo.py | Open | Download |
| exercise.py | Open | Download |
参考
- Hardy, G. H. & Wright, E. M. (1979). An Introduction to the Theory of Numbers (5th ed.). Oxford University Press.
- Knuth, D. E. (1997). The Art of Computer Programming, Vol. 2: Seminumerical Algorithms (3rd ed.). Addison-Wesley.
- Euler, L. (1748). Introductio in analysin infinitorum. (线性筛以欧拉命名)