求逆元的三种方法

逆元是什么?

每个数a均有唯一的一个与之对应的乘法逆元x,使得(a * x)%m = 1
一个数有逆元的充分必要条件是gcd(a,m)=1,此时逆元唯一存在

逆元的含义:模m意义下,1个数a如果有逆元x,那么对于一个数k有k/a=k*x

方法一: 最简便的方法

最简便的一种方法是

这里写图片描述

方法二: 费马小定理

还是上面的例子, 因为除数可能会很大,超过int范围,所以如果当除数特别大的时候就需要求逆元

如果我告诉你我知道 1bmodm 1 b m o d m 的结果会怎么样,那么你就可以用 amodm1bmodm a m o d m 1 b m o d m 就可以得到结果了是不是?

这里 1bmodm 1 b m o d m 就是b相对于m的乘法逆元.

当然我们的费马大大和一众数学家不是这么理解的。费马小定理a ^ (p-1) = 1 (%p),两边同时除去a——a ^ (p-2) = a^-1 (%p),得a的逆元a^-1 = a ^ (p-2)。(参考自链接)。所以我们的(1/b)modm就是b^(mod-2)咯,用快速幂可以快速地完成这个工作。

下面用快速幂的方法来求逆元,但是这里的mod一定要是一个质数

ll inv(ll a,ll p)
{
    ll m=p-2,ans=1;
    while(m)
    {
        if(m&1) ans=ans*n%p;
        m>>=1;
        a=a*a%p;
    }
    return ans;
}

方法三: 扩展欧几里得

但是注意的是当mod是与不是质数的时候求的方法是不一样的,下面用扩展欧几里得求逆元是可以忽略mod是否质数的问题的

给定模数m,求a的逆相当于求解(a * x)%m = 1
这个方程可以转化为ax-my=1
然后套用求二元一次方程的方法,用扩展欧几里得算法求得一组x0,y0和gcd
检查gcd是否为1
gcd不为1则说明逆元不存在
若为1,则调整x0到0~m-1的范围中即可

//a对b求逆元
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    ll t,gcd;
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    gcd=exgcd(b,a%b,x,y);
    t=x,x=y,y=t-a/b*y;
    return gcd;
}
ll inv(ll a,ll b)
{
    ll x,y;
    exgcd(a,b,x,y);
    x%=b;
    x=(x+b)%b;
    return x;
}

int main(){
    ll x,y;//x和y不需要进行初始化
    exgcd(a,b,x,y);
    //(x+m)%m即是a相对于b的乘法逆元
}
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

门豪杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值