欧几里得——GCD引发的讨论

文章字数:728

欧几里得算法

任务

求两个数a,b的最大公约数gcd(a,b)

说明

由贝祖定理[若设a,b是整数,则存在整数x,y,使得ax+by=gcd(a,b)]得,gcd(a,b)=(b,a-b),其中a≥b。通过这样不断的迭代,知道b=0,就是原来数对的最大公约数。考虑到只使用减法会超时,我们观察到如果a-b仍然大于b的话,要进行一次同样的操作,就把a减到不足b为止,所以有gcd(a,b)=gcd(b,a mod b)。由此可以在log的时间内求出两个数的gcd。

程序

int gcd(int a,int b);

复杂度

O(logN),其中N和a,b同阶

输入

a,b两个整数

输出

a,b的最大公约数

代码

1
2
3
int gcd(int a,int b){
        return b  == 0? a : gcd(b, a % b);
}

扩展欧几里得

任务

求出A,B的最大公约数,且求出X,Y满足AX+BY=GCD(A,B)。

说明

要求X,Y,满足:AX+BY=GCD(A,B)。 当B=0时,有X=1,Y=0时等式成立。 当B>0时,在欧几里得算法的基础上,已知: GCD(A,B)=GCD(B,A mod B) 先递归楸树X’,Y’满足: BX’+(A mod B)Y’ = GCD(B,A mod B) = GCD(A,B) 然后可以回推,我们将上式化简得: BX’+(A-A/B*B)Y’=GCD(A,B) AY’+BX’-(A/B)BY’=GCD(A,B) 这里除法指整除。把含B的因式提取一个B,可得: AY’+B(X’-A/BY’)=GCD(A,B) 故X=Y’,Y=X’-A/B&Y’

程序

int extend_gcd(int a,int b,int &x,int &y);

复杂度

O(logN),其中N和a,b同阶

输入

a,b两个整数 &x,&y引用,ax+by=GCD(a,b)的一组解

输出

a,b的最大公约数 调用后x,y满足方程ax+by=GCD(a,b)。

代码

  int extend_gcd(int a,int b,int &x,int &y) {
    if(b==0) {
        x=1;
        y=0;
        return a;
    } else {
        int r=extend_gcd(b,a%b,y,x);
        y-=x*(a/b);
        return r;
    }
}

参考文章

ACM国际大学生程序设计竞赛:算法与实现 百度百科

该内容采用 CC BY-NC-SA 4.0 许可协议。

如果对您有帮助或存在意见建议,欢迎在下方评论交流。

加载中...