扩展欧几里得的推导与代码实现

引言 : 裴蜀定理(定义摘自oi wiki)

定义

  设整数a,b是不全为0的整数,则存在整数x,y,使得 ax+by = gcd(a,b) 

        那么可以推出任意整数解(x,y)得到的ax+by = gcd(a,b)的整数倍

  

证明

   1.若a,b有一个数为0,则x取1即可成立

  2.若a,b都为正整数,gcd(a,b) 为a,b的共同因子

   所以 a%gcd(a,b) = b%gcd(a,b) = 0

   由(m+n)%p = m%p+n%p

   可以得出 (ax+by)%gcd(a,b) = ax%gcd(a,b)+by%(gcd,a,b) = 0+0 = 0  得证

回到今天的主角扩展欧几里得算法(部分借鉴知乎用户忘忧北萱草的文章)

传统欧几里得算法是用辗转相除算出a,b的最大公约数

扩展欧几里得则是可以在既算出最大公约数的同时,算出ax+by = gcd(a,b) 中的(x,y)的一组解

在欧几里得算法中,递归根据的是gcd(a,b) = (b,a%b) = (b,a-b[a/b])  在扩欧里也会用到这个结论

设两组解(x,y) , (x1,y1)  根据裴蜀定理可得ax+by = gcd(a,b) bx1+(a-b[a/b])y1 = (b,a-b[a/b])

由于(a,b) = (b,a-b[a/b])  则将两个式子联立求解得  a(x-y1) + b(y-(x1-y1[a/b])) = 0

我们希望这个式子对于所有解集(x,y) 都成立 于是有 x = y1  y = x1-y1[a/b] 

此时求解(x,y)已经变成了求解(x1,y1),继续递归直到求解完成。递归结束条件为b=0,此时x=1,y=0

代码实现:  

    int exgcd(int a, int b, int& x, int& y)  //返回的是gcd(a,b) x,y要传引用
  {
    if(a < b) return exgcd(b, a, y, x);  
    if(b == 0)                    //递归的结束条件是 b==0
    {
      x = 1; y = 0;
      return a;
    }
    else
    {
      int x1;
      int d = exgcd(b, a % b, x1, x);  
           //exgcd(a,b,x,y) 的实质是一位置乘三位置 + 二位置*四位置 = gcd(一位置,二位置)

      y = x1 - a / b * x;       
          //根据前文第三处黑体字可知  递归函数的三位置应该是x1,四位置应该是y1

      return d;           //因为x=y1 所以四位置是x
    }
  }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

拾墨乄

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

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

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

打赏作者

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

抵扣说明:

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

余额充值