zoukankan      html  css  js  c++  java
  • 【数论】扩展欧几里得算法

    扩展欧几里得

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

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

        在已知(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;
    }
    

      

  • 相关阅读:
    zip 中文文件夹为空问题
    webview长按文本区域不显示文字放大镜等方法
    crash
    精疲力尽先生的造访
    告别忙碌的2017,迎来更加忙碌的2018
    传说中的59分!!
    为什么我一定吵不过女人?
    人挪活!
    低谷时,请读书!
    java小入门的感觉
  • 原文地址:https://www.cnblogs.com/wxjor/p/6087024.html
Copyright © 2011-2022 走看看