数论扩展欧几里得算法

Posted wxjor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论扩展欧几里得算法相关的知识,希望对你有一定的参考价值。

扩展欧几里得

    上回刚写完欧几里得,那现在还有一个东西叫拓展欧几里得:

    扩展欧几里得法是一个在求解同余方程等问题上的一个很好的方法,其具体功能如下:

    在已知(a,b)时,求解一组(p,q)使得p*a+q*b=GCD(a,b)

    

    首先,根据数论中的原理,解一定是存在的。

    我们可以设a对于GCD(a,b)的倍数是k,b对于GCD(a,b)的倍数是l

    那么p*(GCD(a,b)*k)+q*(GCD(a,b)*l)=GCD(a,b)

    可以推出:p*k*GCD(a,b)+q*l*GCD(a,b)=GCD(a,b)

    两边同时除以GCD(a,b),可得p*k+q*l=1

    那么我们求解的是一个二元一次不定方程,它是一定有解的。

  

    其次,因为我们知道GCD(a,b)=GCD(b,a%b)

    所以p*a+q*b=GCD(a,b)=GCD(b,a%b)=p*b+q*a%b=q*(a-a/b*b)=q*a+(p-a/b*q)*b

    这样这个方程就化简为了b与a%b的线性组合。

 

    那么最终的代码是这样的:

#include<iostream>
using namespace std;
int extended_GCD(int a,int b,int &x,int &y){
    if(b==0){
        x=1,y=0;
        return a;
    }
    int ans=extended_GCD(b,a%b,x,y);
    int tmp=x;
    x=y;
    y=tmp-a/b*y;
    return ans;//返回的是GCD(a,b)
}
int main(){
    int a,b,x,y,z;
    cin>>a>>b;
    z=extended_GCD(a,b,x,y);
    cout<<z<<" "<<x<<" "<<y;
    return 0;
}

  

以上是关于数论扩展欧几里得算法的主要内容,如果未能解决你的问题,请参考以下文章

数论初步——扩展欧几里得算法

ACM数论之旅4---扩展欧几里德算法(欧几里德(???)?是谁?)

数论-扩展欧几里得算法

POJ2142 The Balance 数论(扩展欧几里得算法)

数论杂谈——欧几里得算法及扩展欧几里得

数论--扩展欧几里得算法