Files
python/TangDou/AcWing/NumberTheory/逆元/乘法逆元.md
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

4.3 KiB
Raw Blame History

乘法逆元小结

https://www.freesion.com/article/43361201366/

乘法逆元,一般用于求

\large \frac{a}{b} \ \ \ (mod \ \ p)

的值,($p$通常为质数),是解决模意义下分数数值的必要手段。

一、逆元定义

很明显,上述式子只有一条不成立,即 $(a/b) % p$,但是在有些情况下,又需要进行有模运算的除法。因为式子不成立,如果 a 过大或者 b 过大,极易导致计算过程丢失精度,造成结果误差。因此,为了杜绝这一现象,逆元出现了。

若$a\times x \equiv 1 (mod \ b)$,且$a$与$b$互质,那么我们就能定义:

$x$为$a$的逆元,记为a^{-1},所以我们也可以称$x$为$a$在$mod \ b$意义下的倒数。

所以对于 \frac{a}{b}\ (mod \ p) ,我们就可以求出b 在 mod \ p 下的逆元,然后乘上 a ,再 $mod \ p$,就是这个分数的值了。

二、求解逆元的方式

1、费马小定理+快速幂求逆元(p一定要质数)

费马小定理

若$p$为素数,$a$为正整数,且$a、p$互质。则有$a^{p−1}≡1(mod \ p)$。

这个我们就可以发现它这个式子右边刚好为 1 。

所以我们就可以放入原式,就可以得到:

\large a \times x \equiv 1 (mod \ \ p ) \large a \times x \equiv a^{p-1} (mod \ \ p ) \large x \equiv a^{p-2} (mod \ \ p )

所以我们可以用快速幂来算出 $a^{p−2}(mod \ p)$的值,这个数就是它的逆元了

代码也很简单:

typedef long long LL;
LL qmi(LL a, LL k, LL p) {
    LL res = 1;
    while (k) {
        if (k & 1) res = res * a % p;
        k >>= 1;
        a = a * a % p;
    }
    return res;
}

int main() {
    int a, p;
    cin >> a >> p;
    LL x = qmi(a, p - 2, p); // x为a在mod p意义下的逆元
    return 0;
}

2、欧拉定理求逆元(相当于费马小定理的扩展)

解法一的拓展:欧拉定理+快速幂求逆元($p$不一定为质数,但a $p$还是要互质) 一般不用这种办法,因为它能干的,扩展欧几里得都能干! 略

3、扩展欧几里得

注意:($p$不用为质数但$a,p$要互质,不然$a^{-1}$无解)

这个方法十分容易理解,而且对于单个查找效率似乎也还不错,比后面要介绍的大部分方法都要快(尤其对于 mod \ p 比较大的时候)。

这个就是利用拓欧求解 线性同余方程 a∗x≡c(mod \ b) 的$c=1$的情况。我们就可以转化为解 a∗x+b∗y=1 这个方程。

求解这个方程的解。不会拓欧可以点这里~

而且这个做法还有个好处在于,当 a⊥p (互质),但 p 不是质数的时候也可以使用。

代码比较简单:

void exgcd(LL a, LL b, LL &x, LL &y) {
    if (!b) x = 1, y = 0;
    else exgcd(b, a % b, y, x), y -= a / b * x;
}
int main() {
    LL x, y;
    exgcd (a, p, x, y);
    x = (x % p + p) % p;
    printf ("%d\n", x); //x是a在mod p下的逆元
}

4、递推打表

用于求一连串数字对于一个$mod \ p$的逆元。 P3811 【模板】乘法逆元 对于一个区间的逆元,只能用这种方法,别的算法都比这个要慢。

$O(n)$筛$1$到$n$所有数模$p$的逆元:

  • 初值\large Inv[1]=1
  • 设\large p=ki+r,则 \large ki+r \equiv 0 (mod \ p)
  • 两边同乘\large i^{-1}r^{-1},得\large kr^{-1}+i^{-1} \equiv 0 (mod \ p)
  • 移项:\large i^{-1} \equiv -kr^{-1} (mod \ \ p )
  • \large k=\left \lfloor \frac{p}{i} \right \rfloor,所以-k \equiv p- \frac{p}{i} (mod \ \ p )
  • 所以Inv[i]=(p-p/i)*Inv[p%i]%p

三、阶乘逆元 [挖坑待填]

线性求阶乘的逆元 设第$x$项阶乘为x!,其逆元为x!^{-1},那么有递推式:$\large \displaystyle (x-1)^{-1} = (x!)^{-1}*x$ 所以从后往前递推求。

https://blog.csdn.net/qq_52142857/article/details/121032531

https://www.bbsmax.com/A/xl56Pb97zr/

https://blog.csdn.net/kiwi_berrys/article/details/54834977

https://www.freesion.com/article/43361201366/#4__191