HRBU 2022/10/16

 乘法逆元

给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的。

一扩展欧几里得可以求最大公约数。
二求ax+by=gcd(a,b)的解x,y。逆元就包括其中。
x是a的模b乘法逆元,y是b的模a乘法逆元(即gcd()=1时的x/y)

现在来讲一下扩展欧几里得到底怎么来的:
其实我觉得大家只要搞懂后面递归的x,y怎么求就几乎没问题的了。
原式:ax+by=gcd(a,b)
递归:bx+(a%b)y^=gcd(a,b) 【x^和 y^就是上一步的x,y】
其中:a%b=a-(a/b)b
带入后:ay^+b ( x ^ - ( a/b ) y ^ )=gcd(a,b);
再与原式对比:ax+by=gcd(a,b)
得出:{
x=y^;
x^-(a/b ) y ^=y;
}

这就是递归过程中,x和y的由来
而当b=0时,有:(递归结束时){a=gcd(a,b),x=1,y=0}
a1+b0=a=gcd(a,b)
可得出一个特解a(最大公约数)

这样就可以得到每两个相邻状态的x和y的转化了,就可以在求gcd(a,b)的同时求对x,y求解

相信对于扩展欧几里得算法,大家会有疑问为什么b=0时x=1;y=0?
其实当达到递归基时,此时的a就是gcd(最大公约数),b=0,那么有ax+by=a。
故x必须等于1,y可以取任何正整数。

我还是有疑问上面说了“x是a的模b乘法逆元,y是b的模a乘法逆元”
大家都统一b=0时x=1;y=0;。既然y可以取任何正整数那么我就要换一个当b=0时:x=1;y=1;这个“x是a的模b乘法逆元,y是b的模a乘法逆元”结论还是成立的。

还有一点就是建议y取0,如果取其他数组,由于y增长较快,可能会有越界的问题。
 

int exGcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    int gcd=exGcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-(a/b)*y;
    return gcd;
}
signed main()
{
    int n,m;
    int x,y;
    cin>>m>>n;
    if(exGcd(n,m,x,y)==1)
    {
        cout<<(y%n+n)%n<<endl;
    }
    else
    {
        cout<<-1<<endl;
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

活在当下 北乔

不爱多bb,朴实一句话:感谢您

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

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

打赏作者

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

抵扣说明:

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

余额充值