乘法逆元
前置知识
二元线性丢番图方程
形如 \(ax + by = c\) 的方程称为二元线性丢番图方程,其中 \(a, b, c \in \Z\).
在后文中如无特殊说明默认一个二元线性丢番图方程的系数均为整数.
裴蜀定理
对于一个二元线性丢番图方程 \(ax + by = c\),记 \(d = \gcd(a, b)\),其存在整数解的充要条件是 \(d \mid c\).
如果存在一组整数解 \((x_0, y_0)\),则所有解可以表示为 \(x = x_0 + \dfrac{b}{d} \cdot k, y = y_0 - \dfrac{a}{d} \cdot k\),其中 \(k \in \Z\).
同余与同余式
\(\forall a, b \in \Z, m \in \N_+\),若 \(m \mid (a - b)\), 则称 \(a\) 和 \(b\) 关于 \(m\) 同余, 记作 \(a \equiv b \pmod m\).
一元线性同余方程
若 \(x\) 是未知数,给定 \(a, b, m\),且 \(a, b, m \in \Z\),求整数 \(x\),满足 \(ax \equiv b \pmod m\).
欧几里得算法(辗转相除法)
\(\forall a, b \in \N_+\),有 \(\gcd(a,b) = \gcd(b, a \bmod b)\).
扩展欧几里得算法
求二元线性丢番图方程的整数解
对于一个二元线性丢番图方程 \(ax + by = c\), 根据裴蜀定理, 当且仅当 \(\gcd(a, b) | c\) 时, 方程有整数解.
故可以先求
的解,再在等式两边乘以 \(\dfrac {c}{\gcd(a, b)}\),即可得到原方程的解.
由欧几里得算法我们可以得到
那么我们可以再列出一个二元线性丢番图方程
整理一下
对于欧几里得算法的流程而言,求解 \(\gcd(b, a \bmod b)\) 是 求解 \(\gcd(a, b)\) 的下一层状态,或者说是子问题,在欧几里得算法回溯时我们需要根据 \(bx_1 + (a \bmod b)y_1 = \gcd(b, a \bmod b)\) 的解来推导 \(ax + by = \gcd(a, b)\) 的解,接下来我们需要探究两方程解的关系.
因为有
所以
又有
将其带入等式中可得
整理等式
将等式左右两项分别对应可得
在欧几里得算法的最终状态我们可以得到 \(a = \gcd(a, b), b = 0\),此时方程 \(ax + by = \gcd(a, b)\) 的解显然是 \(x = 1, y = 0\). 由于欧几里得算法是递归的,故我们可以通过 \(x = 1, y = 0\) 以及刚才得出的结论逆推.
此时我们求的是 \(ax + by = \gcd(a, b)\) 的一组解,我们可以在等式两边同时乘以 \(\dfrac {c}{\gcd(a, b)}\),就可以求得 \(ax + by = c\) 的解.
显然这只是方程的一组特解,记刚才所得的特解为 \(x_0, y_0\),那么方程的通解为 \(x = x_0 + \dfrac{b}{\gcd(a, b)} \cdot k, y = y_0 - \dfrac{a}{\gcd(a, b)} \cdot k, k \in \Z\).
代码如下.
int Exgcd(int a, int b, int &x, int &y)
{
if (b == 0)
{
x = 1; y = 0;
return a;
}
int ans = Exgcd(b, a % b, x, y);
int tmp = x;
x = y;
y = tmp - a / b * y;
return ans;
}
求一元线性同余方程的解
根据同余的定义我们可以知道,对于一个一元线性同余方程 \(ax \equiv b \pmod m\),一定有 \(m \mid (ax - b)\).
也就是说 \((ax - b)\) 一定是 \(m\) 的倍数. 我们假设 \((ax - b)\) 是 \(m\) 的 \(-y\) 倍,那么
这其实就是一个二元线性丢番图方程. 所以求解一个一元线性同余方程等价于求解一个二元线性丢番图方程.
利用扩展欧几里得算法求乘法逆元
在进行模运算时,有时需要对分数取模,但是 \(\dfrac{b}{a} \bmod m \ne \dfrac{b \bmod m}{a \bmod m}\),这时就需要一个 \(x\) 来代替 \(\dfrac{1}{a}\),使得
那么
即
这时就将 \(x\) 称为 \(a\) 模 \(m\) 时的乘法逆元,记作 \(a^{-1} \pmod m\) 或者 \(\text{inv}(a)\).
根据裴蜀定理,当且仅当 \(\gcd(a, m) \mid 1\) 时, \(ax \equiv 1 \pmod m\) 有整数解,即 \(a\) 存在乘法逆元. 很容易得出此时 \(\gcd(a,m) = 1\),即 \(a\) 与 \(m\) 互质.
回顾线性同余方程的标准形式
那么 \(a\) 的乘法逆元就是 \(b = 1\) 时方程的解,用扩展欧几里得算法求解即可.
费马小定理求解
若有 \(a, m \in \Z\),\(m \nmid a\) 且 \(m\) 为质数,则有 \(a^{m - 1} \equiv 1 \pmod m\).
将式子变形 \(a \cdot a ^ {m - 2} \equiv 1 \pmod m\).
根据乘法逆元的定义可以得到 \(a\) 在模 \(m\) 意义下的乘法逆元为 \(a ^ {m - 2}\),用快速幂求解即可.
线性递推求解
线性递推解法可以在 \(\mathcal{O}(m)\) 时间复杂度内求解区间 \([1, n]\) 内所有数关于 \(m\) 的乘法逆元 \((n < m)\).
首先,易得 \(\text{inv}(1) = 1\).
\(\forall i \in [1, n] 且 i \in \Z\),设 \(m = ki + r\),其中 \(k, r \in \Z\),有
两边同时乘以 \(i^{-1}r^{-1} \pmod m\),得
移项,得
又有
代入得
又有
可知
故 \(\text{inv}(r)\) 一定在求解 \(\text{inv}(i)\) 之前就已经推导出.那么
为了防止出现负数,可在等式右边加上 \(m\),因为 \(m \bmod m = 0\),故不会对答案产生影响.