乘法逆元

乘法逆元

乘法逆元可以求出 $ \displaystyle {\frac {a}{b}} $ 在取模 \(P\) 的意义下的数值。

逆元

\(a * x \equiv 1 \pmod q\) ,且 \(a\)\(b\) 互质,那么我们定义: \(x\)\(a\) 的逆元,记作 \(a^{-1}\) ,也可以称 \(x\)\(a\) 在 $ \pmod p$ 意义下的倒数。

对于 \(\displaystyle {\frac {a} {b}} \pmod p\) ,它的值为 \(a * b^{-1} \ \ mod \ \ p\)

求解逆元

快速幂

费马小定理
\(p\) 为素数,\(a\) 为正整数,且 \(a、p\) 互质。则有 \(a^{p-1} \equiv 1 \pmod p\)

\(x\)\(a\) 的逆元,则:

\[\begin{aligned} a * x &\equiv 1 \pmod p \\ a * x &\equiv a^{p-1} \pmod p \\ x &\equiv a^{p-2} \pmod p \end{aligned} \]

所以我们可以使用快速幂求出 \(a^{p-2} \pmod p\) 的值,即为 \(a\) 的逆元。

int qmi (int a, int k, int mod)
{
    int res = 1;
    while (k)
    {
        if (k & 1) res = 1ll * a * res % mod;
        a = 1ll * a * a % mod;
        k >>= 1;
    }
    return res;
}

拓展欧几里得
在模数不为质数时,不能使用费马小定理,但是可以使用拓展欧几里得求逆元,参考此处

线性算法

线性算法可以求出连续数字 \(1 \sim n\) 对于 \(\pmod p\) 的逆元。

首先有 \(1^{-1} \equiv 1 \pmod p\)

假设现在要求 \(i\) 的逆元,显然 \(p = \lfloor{\dfrac p i}\rfloor * i + p \% i\)

那么,在模 \(p\) 的情况下:

\[p = \lfloor{\dfrac p i}\rfloor * i + p \% i \equiv 0 \pmod p \]

\[\begin{equation} \begin{split} \lfloor{\dfrac p i}\rfloor * i &\equiv -(p \% i) \pmod p \\ \lfloor{\dfrac p i}\rfloor * -(p \% i)^{-1} &\equiv i^{-1} \pmod p \\ i^{-1} &\equiv -\lfloor{\dfrac p i}\rfloor * (p \% i)^{-1} \pmod p \\ \end{split} \end{equation} \]

注意到 \(p \% i\) 一定是小于 \(i\) 的,这样我们就可以从前面推出后面了。

时间复杂度:$ O(n) $

inv[1] = 1;
for (int i = 2; i <= n; i ++ )
    inv[i] = (p - p / i) * inv[p % i] % p; // 取模意义下 -a = p - a

阶乘逆元

根据阶乘递推关系:

\[\begin{split} inv[i+1] &= \displaystyle {\frac{1}{(i+1)!}} \\ inv[i+1] * (i + 1) &= \displaystyle {\frac{1}{i!}} \end{split} \]

所以我们也可以先求出 \(n!\) 的逆元,再逆推,就可以得到 \(1! \sim n!\) 的逆元。

递推式: \(inv[i+1] * (i+1) = inv[i]\)

最后可以使用 \(\displaystyle {\frac{1}{i!}} * (i-1)! = \frac{1}{i}\)

时间复杂度为 \(O(n)\)

posted @ 2021-11-20 14:10  Horb7  阅读(66)  评论(0编辑  收藏  举报