zoukankan      html  css  js  c++  java
  • 扩展欧几里得(学习笔记)

    贝祖定理:对于任意整数a,b,存在一对整数x,y,满足(ax+by=gcd(a,b)).

    以下证明中的[ ]是向下取整的意思(主要是我不会打向下取整的符号)

    证明:数学归纳法.在欧几里得算法最后一步中,即b=0时,显然有一对整数x=1,y=0,使得(a*1+0*0=gcd(a,0));若b>0,则(gcd(a,b)=gcd(b,amod b)).假设存在一对整数x,y,满足(b*x+(a mod b)*y=gcd(b,a mod b)),因为(bx+(a mod b)y=bx+(a-b[a/b])y),继续整理式子得(ay+b(x-[a/b]y)),所以令(x'=y)(y'=x-[a/b]y),就得到了(ax'+by'=gcd(a,b)).因为x'和y'一定都是整数,所以定理是成立的.

    根据上述定理和证明,有扩展欧几里得算法:

    int exgcd(int a,int b,int &x,int &y){
         if(b==0){x=1;y=0;return a;}
         int d=exgcd(b,a%b,x,y);
         int z=x;x=y;y=z-y*(a/b);
         return d;
    }
    

    还有一种写得更多的写法,个人认为更好理解:

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

    拓展:

    对于更一般的方程(ax+by=c),它有解当且仅当(gcd(a,b)|c).

    (d=gcd(a,b)),我们可以先用扩展欧几里得求出(ax+by=d)的一组特解(x_0)(y_0),然后令(x_0),(y_0)同时乘上(c/d),就得到方程(ax+by=c)的一组特解((c/d)*x_0),((c/d)*y_0),所以通解就是((c/d)*x_0+k*(b/d)),((c/d)*y_0+k*(a/d)),其中k是整数.

    扩展欧几里得算法有一个常见的应用:求解线性同余方程.

    给定整数a,b,m,求一个整数x满足(a*x ≡ b(mod m)),或者给出无解.因为未知数的指数为1,所以称为一次同余方程,也称线性同余方程.

    (a*x ≡ b(mod m)) 方程可以改写为(a*x+m*y=b).这就回到了上面的拓展内容.

    推荐两道模板题练练手,同余方程青蛙的约会

  • 相关阅读:
    vue中引用font-awesome
    创建VUE项目
    Core项目添加EF
    DBHelper,之前常用的代码,保存起来。
    appium+python的APP自动化(2)
    appium+python的APP自动化(1)
    单例模式
    双重检测机制解决缓存穿透问题
    mysql数据库
    java的三大特性----封装、集成、多态
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10500698.html
Copyright © 2011-2022 走看看