乘法逆元

乘法逆元是群论里非常重要的一个定义,这里不涉及群论,只探讨其定义和求法。

定义:

如果有ab ≡ 1(modp),则称b是mod p意义下a的乘法逆元。记b=inv(a) 或 b=a-1

定义介绍完了,下面说说它的几种求法。

方法一:欧拉筛

第一想法很容易就能想到,对于每个合数 a ,我们把所有它的因子的逆元筛出来再相乘即可。(不要说枚举这种操作)但是,这个方法非常慢,所以我们要寻找更快的理论。

方法二:扩展欧几里得

对于ax ≡ 1(modp),可以转化为ax = kp + 1,移项就可以用exgcd求了,复杂度o(nlogn)。

#include <iostream>
long long exgcd(long long a, long long b, long long &x, long long &y)
{
    if(a == 0 && b == 0)
        return -1;
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    long long d = exgcd(b, a%b, y, x);
    y -= a/b*x;
    return d;
}
long long mod_reverse(long long a, long long n)
{
    long long d = exgcd(a, n, x, y);
    if(d == 1)
        return (x%n+n) % n;
    else
        return -1;
}

方法三:费马小定理

费马小定理:当 p 为素数时, ap-1=1 (mod p) 。那么 a * ap-2 = 1 (mod p) 。快速幂求出 ap-2 即可,复杂度o(nlogn)。

方法四:欧拉定理

由aφ§ ≡ 1 (mod p) 得 aφ(p)−1是a的逆元,同样的用快速幂求。
其中,φ(x)=x * (1 - 1 / p1)(1 - 1 / p2)(1 - 1 / p3)(1 - 1 / p4) …… (1 - 1 / pn) ,其中p1,p2 … pn为 x 的所有质因数,x是正整数, φ(1)=1。注:每种质因数只有一个。
(https://blog.csdn.net/Lytning/article/details/24432651 这个是欧拉函数线性筛的博客)

方法五:线性递推

在这里插入图片描述
(从这个大佬的博客里找到的 https://blog.csdn.net/sdfzchy/article/details/76098066)
于是得到, inv[i] = (mod - mod / i) * inv[mod%i] % mod,时间复杂度o(n)。

void inv(LL mod)
{
    inv[1] = 1;
    for(int i = 2; i <= mod-1; i++)
    {
        inv[i] = (mod - mod / i) * inv[mod%i] % mod;
    }
}

PS:

1、在求解a / b % m时,可以转化为(a % (b * m)) / b。
证明:令k = (a / b) / m(向下取整), x = (a / b) % m,
a / b = k * m + x (x < m),
a = k* b * m + b * x,
a % (b * m) = b * x,
a % (b * m) / b = x,
a / b % m = a % (b * m) / b。
证毕。
(公式适用于很多情况:m不必是素数,b和m也不必互质)
上面的公式适用于b较小,a需要在线求且较大的时候。
2、求组合数的时候可以用逆元打表求,结合递推和费马小定理。

fac[0] = 1;
for(int i = 1; i <= MAX; i++)
    fac[i] = (fac[i - 1] * i) % MOD;
inv_fac[MAX] = qpow(fac[MAX], MOD - 2);
for(int i = MAX - 1; i >= 0; i--)
    inv_fac[i] = (inv_fac[i + 1] * (i + 1)) % MOD;

差不多就是这些吧,还有新的东西还会补充。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值