• 基础数论--扩展欧几里得算法


    正常的欧几里得算法

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

    可以在O(n)的时间复杂度内,求出a和b两数的最大公约数。

    而扩展欧几里得算法则可以在求出最大公约数的同时,求出两个数x,y,使得x*a+y*b=gcd(a,b),用处就是可以用来求解线性同余方程(写在下边)

     1 //推荐第二种写法
     2 #include<iostream>
     3 using namespace std;
     4 int exgcd1(int a,int b,int& x,int& y){
     5     if(b==0){
     6         x=1,y=0;
     7         return a;
     8     }else{
     9         int d=exgcd1(b,a%b,x,y);
    10         int t=y;
    11         y=x-(a/b)*y;
    12         x=t;
    13         return d;
    14     }  
    15 }
    16 int exgcd2(int a,int b,int& x,int& y){
    17     if(b==0){
    18         x=1,y=0;
    19         return a;
    20     }else{
    21         int d=exgcd2(b,a%b,y,x);
    22         y=y-(a/b)*x;
    23         return d;
    24     }
    25 }
    26 int main(void){
    27     int n;
    28     cin>>n;
    29     for(int i=0;i<n;i++){
    30         int a,b,x,y;
    31         cin>>a>>b;
    32         exgcd2(a,b,x,y);
    33         cout<<x<<" "<<y<<endl;
    34     }
    35     return 0;
    36 }

    第一种证明,第二种类似

    求解同余方程

    同余方程的定义,给定a,b,m,求出一个满足条件的x,使得a*x=b(mod m)。

    也就是a*x=b+y*m,令y′=-y,得

    x*a+ y′ *m=b,这就和上边的扩展欧几里得完全符合

     1 #include<iostream>
     2 using namespace std;
     3 typedef long long LL;
     4 int exgcd(int a,int b,int& x,int& y){
     5     if(b==0){
     6         x=1,y=0;
     7         return a;
     8     }else{
     9         int d=exgcd(b,a%b,y,x);
    10         y=y-(a/b)*x;
    11         return d;
    12     }
    13 }
    14 int main(void){
    15     int n;
    16     cin>>n;
    17     for(int i=0;i<n;i++){
    18         int a,b,m;
    19         int x,y;
    20         cin>>a>>b>>m;
    21         int d=exgcd(a,m,x,y);
    22         if(b%d==0){
    23             cout<<(LL)(b/d)*x%m<<endl;//%m是为了保证答案在m的范围内
    24                                       //% m 仍然是正确的是因为,相当于将y′增加了
    25         }else{
    26             cout<<"impossible"<<endl;
    27         }
    28     }
    29     return 0;
    30 }

    既然能解同余方程的话,那就能够求逆元,只不过逆元是更加特殊的情况,b=1

    具体的可以翻一翻博客。

  • 相关阅读:
    servlet遇到的问题
    servlel出现404问题★ 出现不自动映射 设置XML的问题时候
    c3p0的错误mchange.v2.ser.Indirector
    【转】JSON和JSONP
    性能测试理论
    如何解决包冲突问题
    一方包、二方包、三方包是什么?
    利用selenium webdriver点击alert提示框
    采用Spring管理Bean和依赖注入
    Java加载jar文件并调用jar文件当中有参数和返回值的方法
  • 原文地址:https://www.cnblogs.com/greenofyu/p/14107420.html
Copyright © 2020-2023  润新知