拓展欧几里得算法

上一篇:欧几里得算法


概念:

对于不全为0的非负整数 a , b a,b a,b gcd ⁡ ( a , b ) \gcd(a, b) gcd(a,b) 表示 a , b a,b a,b 的最大公约数,必然存在整数对 x , y x,y x,y ,使得 g c d ( a , b ) = a x + b y gcd(a,b) = ax + by gcd(a,b)=ax+by
给定 a a a b b b ,拓展欧几里得算法可以计算出这个整数对 x , y x,y x,y

证明&&基本算法:

(以下证明过程中所有的 / / / 均为整除)

a > b a > b a>b

  1. b = 0 b=0 b=0
    gcd ⁡ ( a , b ) = a \gcd(a,b)=a gcd(a,b)=a 。此时 x = 1 , y = 0 x=1,y=0 x=1,y=0
  2. b ≠ 0 b≠0 b̸=0
    ∵ a > b > 0 \because a>b>0 a>b>0
    ∴ a ≠ 0 \therefore a\ne 0 a̸=0
    a x 1 + b y 1 = gcd ⁡ ( a , b ) ax1+\qquad b\qquad y1=\gcd(a,b) ax1+by1=gcd(a,b)
    b x 2 +   ( a   m o d   b )   y 2 = gcd ⁡ ( b , a   m o d   b ) \quad bx2+\ (a\bmod b)\ y2=\gcd(b,a\bmod b) bx2+ (amodb) y2=gcd(b,amodb)
    ∵ gcd ⁡ ( a , b ) = gcd ⁡ ( b , a   m o d   b ) ∵\gcd(a,b) = \gcd(b,a\bmod b) gcd(a,b)=gcd(b,amodb)(欧几里得原理)
    ∴ a x 1 + b y 1 = b x 2 + ( a   m o d   b ) y 2 ∴ax1+by1 = bx2+(a\bmod b)y2 ax1+by1=bx2+(amodb)y2
    ​ 即 a x 1 + b y 1 = b x 2 + ( a − ( a / b ) × b ) y 2 = b x 2 + a y 2 − ( a / b ) × b y 2 = a y 2 + b x 2 − ( a / b ) × b y 2 \!\begin{aligned} 即ax1+by1 &= bx2 + (a - (a/b) × b)y2 \\ &=bx2 + ay2-(a/b)×by2 \\ &=ay2 + bx2-(a/b) × by2 \end{aligned} ax1+by1=bx2+(a(a/b)×b)y2=bx2+ay2(a/b)×by2=ay2+bx2(a/b)×by2
    根据恒等定理得 x 1 = y 2 , y 1 = x 2 − ( a / b ) × y 2 x1 = y2,y1 = x2 - (a/b) × y2 x1=y2,y1=x2(a/b)×y2
    利用上式,我们就可以将求 x 1 , y 1 x1,y1 x1,y1 转化为求 x 2 , y 2 x2,y2 x2,y2

因为 gcd ⁡ \gcd gcd 不断的递归求解过程中,一定会出现 b = 0 b=0 b=0 的情况,所以递归可以结束。

我们可以得出两点:

  1. 必然存在满足条件的整数对 x , y x,y x,y ,原命题得证。
  2. 算法是正确的,且时间复杂度仅为 log ⁡ \log log 级别。

代码实现

  1. 递归实现的代码

    int exgcd(int a,int b,int &x,int &y) 
    //最终答案存在x和y里面,函数值返回的是两数的gcd
    {
    	if (b==0) //递归边界
    	{
    		x=1; //可参考证明过程
    		y=0; //同上
    		return a;
    	}
    	int r=exgcd(b,a%b,x,y),t=x; //t是临时变量,保留x的值
    	x=y; //可参考证明过程
    	y=t-a/b*y; //同上
    	return r;
    }
    
  2. 非递归实现(无需掌握,甚至都无需了解)

    int exgcd(int m,int n,int &x,int &y) 
    //最终答案存在x和y里面,函数值返回的是两数的gcd
    {
    	int x1,y1,x0,y0;
    	x0=1; y0=0;
    	x1=0; y1=1;
    	x=0; y=1;
    	int r=m%n;
    	int q=(m-r)/n; //等同于m/n
    	while (r) //余数不为零
    	{
    		x=x0-q*x1;    y=y0-q*y1; //可参考证明过程
    		x0=x1;        y0=y1;     //迭代
    		x1=x;         y1=y;      //迭代
    		m=n; n=r; r=m%n;
    		q=(m-r)/n;
    	}
    	return n;
    }
    

后记

拓展欧几里得算法也可以用来求 a a a b b b 意义下的逆元:

  • gcd ⁡ ( a , b ) > 1 \gcd(a,b)>1 gcd(a,b)>1 时,显然逆元不存在;
  • gcd ⁡ ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1 时,可用拓展欧几里得算法求出 x , y x,y x,y 满足 a x + b y = gcd ⁡ ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b)
    在膜 b b b 的意义下,上式即为 a x ≡ 1 ( m o d b ) ax\equiv 1 \pmod b ax1(modb) 。所以 x x x 就是 a a a b b b 意义下的逆元。

在模数不为质数时,求逆元通常都采用这种方法。


LaTeX \LaTeX LATEX M a r k d o w n \rm Markdown Markdown 打得好累啊,如果对您有帮助的话,请点个赞再走吧QAQ

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值