文章相关
写在前面
填坑。
本文中涉及的概念较少,将不在给出相关概念。
鸣谢
参考资料:《算法竞赛进阶指南》 李煜东 著。
正文
基本工具 欧几里得算法
欧几里得算法之辗转相除法是求解同余方程相关问题一种非常好用的工具。
网上讲这个的很多,讲的也都不错,这里不再赘述。
线性同余方程
解法 - 线性同余方程
线性同余方程解法可以直接使用一次欧几里得算法解决。
(下文中引用内容皆来自 《算法竞赛进阶指南》 李煜东 著)
线性同余方程
给定整数 (a, b, m),求线性同余方程 (ax equiv b (mod m)) 的解 (x)。
原方程等价于 (ax + my = b (y in mathbb Z))。根据裴蜀定理和推论,该线性同余方程组有解当且仅当 (gcd(a, m) | b)。
求解时,先用欧几里得求出一组整数解 (x_0, y_0) 满足 (ax_0 + my_0 = gcd(a, m)),然后 (x = frac{x_0b}{gcd(a, m)}) 就是原方程组的一个特解。方程的通解为 (x_t = x + tm (t in mathbb Z))
例题 - 线性同余方程
代码 - 线性同余方程
线性同余方程组
解法 - 线性同余方程组
中国剩余定理 (CRT)
对于线性同余方程组 (x equiv a_i (mod m_i), i in {1, 2, cdots, n}),若 (m_i) 两两互质, 那么设 (m = prod_{i = 1}^{n} m_i, M_i = frac{m}{m_i}, t_i) 是线性同余方程 (M_it_i equiv 1(mod m_i)) 的一个解, 那么方程组的解为 (sum_{i = 1}^na_iM_it_i)。
证明略。
解法:使用 (n) 次欧几里得,求出 (t_i),得到答案。
其实主要用到的还是 exCRT。
exCRT 可以在模数不满足两两互质的情况下得到线性同余方程组的解。
求解过程:
考虑使用数学归纳法,现在假设已经求出了前 (k - 1) 个线性同余方程构成的方程组的解 (x)。设 (m = operatorname{lcm}{m_i}(i in {1, 2, cdots, k - 1})), 则 (x = tm (t in mathbb Z)) 是前 (k - 1) 个线性同余方程的通解。
那么考虑第 (k) 个方程,找到一个整数 (t) 满足 (x + tm equiv a_k (mod m_k)) 该方程等价于线性同余方程 (mt equiv a_k - x (mod m_k))。这是一个线性同余方程,可以使用欧几里得算法解决。
例题 - 线性同余方程组
代码 - 线性同余方程组
高次同余方程
解法 - 高次同余方程
求解形如 (a^x equiv m) 的高次同余方程一般使用 BSGS 算法。
BSGS 的思想是,计 (t = sqrt{m}),设 (x = it - j),则 (a^x equiv b (mod m)) 转化为 ((a^t)^i equiv ba^j(mod m))。由于 (j > t) 时原式等价于 ((i + 1)t - (j - t)),因此 (j in [0, t)),因此可以存下 (j in [0, t)) 的时候分别的 (ba^j mod m) 的值。又由于 (ij < m) 因此 (i in [0, t])。计算出 (i in [0, t]) 时分别的 ((a^t)^i mod m) 的值,然后找到原先右式计算值中有没有与计算结果同余的。如果有,就更新一下最小答案。
例题 - 高次同余方程
代码 - 高次同余方程
学到了什么
- 欧几里得算法
- CRT
- BSGS