逆元定义

如果 $ax\equiv 1\pmod p$,则称 $x$ 为 $a$ 在模 $p$​ 意义下的乘法逆元。

逆元存在当且仅当 $a\perp p$,即 $\gcd(a,p)=1$​。

将 $ax\equiv 1\pmod p$ 转化可得 $x\equiv\dfrac{1}{a}\pmod p$,那么模意义下 $t \div a$ 就相当于 $t \times x$。

快速求单个数的逆元

快速幂

费马小定理

当 $p\not\mid a$ 且 $p\in\mathbb{P}$ 时,有
$$ a^{p-1}\equiv 1\pmod p $$

由此转化可得 $a\times a^{p-2}\equiv 1\pmod p$,此时就可以发现 $a^{p-2}$ 即为 $a$ 在模 $p$ 意义下的乘法逆元。

此时可以用快速幂计算逆元,时间复杂度 $O(\log p)$。

扩展欧几里得算法

$\text{Exgcd}$ 也可以用于求逆元。

由裴蜀定理可知,若 $a\perp p$,则必然 $\exist\, y$,使得 $a\times x+p\times y=1$​ 成立。

容易发现,$a\times x+p\times y=1\Leftrightarrow a\times x\equiv 1\pmod p$。

使用 $\text{exgcd}$ 解出这个方程即可,时间复杂度 $O(\log p)$。

线性求 $1\sim n$​ 的逆元

例题:loj #110. 乘法逆元


现要求在 $O(n)$ 的时间内,求出模 $m$ 的意义下,$[1,m)$ 中所有数的乘法逆元。

容易发现,$\forall\, m\in\mathbb{Z}$,有 $1 \times 1 \equiv 1\pmod m$,所以 $1$ 的逆元恒为 $1$。

考虑 递推

假设我们已知 $[1,x)$ 内所有数的逆元,需要求出 $x$ 的逆元。

将模数 $m$ 表示为 $kx+t$,其中 $k=\Big\lfloor\dfrac{m}{x}\Big\rfloor$,$t=m\bmod x$。

由此可得 $kx+t\equiv 0\pmod m$。

两边同乘 $x^{-1}\times t^{-1}\pmod m$,可得
$$
\begin{aligned}
kx\times x^{-1}\times t^{-1}+t\times x^{-1}\times t^{-1}\equiv 0\pmod m\
k\times t^{-1}+x^{-1}\equiv 0\pmod m\

\end{aligned}
$$
即可得 $x^{-1}\equiv k\times t^{-1}\pmod m$​。

在此基础上代入 $k=\Big\lfloor\dfrac{m}{x}\Big\rfloor$,$t=m\bmod x$,可得
$$ x^{-1} \equiv -\Big\lfloor\dfrac{m}{x}\Big\rfloor(m\bmod x)^{-1}\pmod m $$
由于 $(m\bmod x)^{-1}\in[1,x)$,所以 $(m\bmod x)^{-1}$​ 已知,线性递推即可。

  • $\textbf{PS 1}$:当 $m\bmod x=0$ 时 $x$ 不存在模 $m$ 意义下的乘法逆元。
  • $\textbf{PS 2}$:由于 $\text{C++}$ 中负数取模的结果为负数,所以在实际实现时递推式应写为 (m - m / x) * inv[m % x] % m

综上所述,递推式即为:
$$ x^{-1}= \begin{cases} 1&x=1\\ -\Big\lfloor\dfrac{m}{x}\Big\rfloor(m\bmod x)^{-1}&x\not=1 \end{cases} \pmod m $$
线性递推即可在 $O(n)$ 的时间内完成。

线性求任意 $n$ 个数的逆元

例题:loj #161 乘法逆元 2


显然,对于每一个数用 快速幂 / $\text{exgcd}$ 求解,时间复杂度为 $O(n\log p)$,无法通过本题。

考虑使用前缀积 $\{s_n\}$,其中 $s_i$ 记录 $\prod_{j=1}^{i}a_j$​​。

此外需要前缀积的逆元,使用 $\{t_n\}$ 序列,其中 $t_i=s_{i}^{-1}\pmod p$。

接下来可以通过 快速幂 / $\text{exgcd}$ 求解 $s_n$ 的逆元,记为 $t_n$​​。

接下来可以通过如下公式线性递推求出 $\{t_n\}$:
$$ t_i \equiv s_i^{-1} \equiv \dfrac{1}{\prod_{j=1}^{i}a_j} \equiv \dfrac{a_{i+1}}{\prod_{j=1}^{i+1}{a_j}} \equiv a_{i+1}\times s_{i+1}^{-1} \equiv a_{i+1}\times t_{i+1}\pmod p $$
记原序列的逆元为 $\{\text{inv}_n\}$,其中 $\text{inv}_i=a_{i}^{-1}\pmod p$。

由于已知前缀积数组的逆元,那么
$$ \text{inv}_i \equiv a_{i}^{-1} \equiv \dfrac{1}{a_i} \equiv \dfrac{1}{\dfrac{s_i}{s_{i-1}}} \equiv \dfrac{s_{i-1}}{s_i} \equiv s_{i-1}\times t_{i} $$
故递推即可,时间复杂度为 $O(n+\log p)$,其中 $O(\log p)$ 是求 $s_n$ 逆元的复杂度。