zoukankan      html  css  js  c++  java
  • 拓展欧几里德算法

    拓展欧几里德算法

    对贝祖等式:ax+by=gcd(a,b);  一定存在整数解,求x最小的整数解x,y (x,y可以是负数)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn=1000100;
    const int INF=(1<<28);
    
    /**
    求解贝祖等式ax+by=gcd(a,b)的最小整数解(x最小)
    */
    int a,b;
    int x,y;
    
    int exgcd(int a,int b,int &x,int &y)
    {
        if(b==0){
            x=1;y=0;
            return a;
        }
        int r=exgcd(b,a%b,x,y);
        int t=y;
        y=x-a/b*y;
        x=t;
        return r;
    }
    
    int main()
    {
        while(cin>>a>>b){
            exgcd(a,b,x,y);
            cout<<"x="<<x<<endl;
            cout<<"y="<<y<<endl;
        }
        return 0;
    }
    View Code

    拓展欧几里德的应用如下

    1,解不定等式:px+qy=r

    思路:显然,当且仅当gcd(p,q)%r==0时有整数解。令d=gcd(p,q),两边同时乘以r/d,再进行exgcd解,最后将解乘以d/r即可

    代码略。。

    2,解模线性同余方程:ax=b(mod n)

    思路:容易知道,即解ax+ny=b中的x,显然,当且仅当gcd(a,n)%b==0时有解。方法同上,但需将解mod n,代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn=1000100;
    const int INF=(1<<28);
    
    /**
    求解模线性同余方程:ax=b(mod n)的最小整数解
    */
    int a,b,n;
    int x,y;
    
    int exgcd(int a,int b,int &x,int &y)
    {
        if(b==0){
            x=1;y=0;
            return a;
        }
        int r=exgcd(b,a%b,x,y);
        int t=y;
        y=x-(a/b)*y;
        x=t;
        return r;
    }
    
    bool mod_linear_equation(int a,int b,int n)
    {
        int d=exgcd(a,n,x,y);
        if(b%d) return false;
        x=x*(b/d)%n;///最小解
        x=(x%(n/d)+(n/d))%(n/d); ///最小正整数解
        for(int i=1;i<d;i++) cout<<(x+i*(n/d))%n<<endl;///打印所有解
        return true;
    }
    
    int main()
    {
        while(cin>>a>>b>>n){
            if(mod_linear_equation(a,b,n))
                cout<<"x="<<x<<endl;
            else cout<<"no solve"<<endl;
        }
        return 0;
    }
    View Code

    3,求解模的逆元,现在没学,以后补上

    更多介绍:http://www.acmerblog.com/extend-gcd-5610.html

    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    MTU 理解和遇到的一些问题
    tm使用
    C++字符串中转义符
    安卓系统修改host文件简单教程
    公有继承的一个理解
    模板打印函数
    linux 设置时区
    ACE中的inline
    SecureCRT中脚本进行交互,发送Ctrl+C
    C++中多态的实现原理
  • 原文地址:https://www.cnblogs.com/--560/p/4372673.html
Copyright © 2011-2022 走看看