扩展欧几里德算法

    扩展欧几里德算法

   扩展欧几里德算法是用来在已知a, b求解一组x,y [x,y都是整数],使它们满足贝祖等式: ax+by = gcd(a, b) =d(解一定存在,根据数论中的相关定理)。扩展欧几里德常用在求解模线性方程及方程组中。

   证明

    当 b=0 gcd(a,b)=a。此时 x=1,y=0;

      ax+by = gcd(a, b);

      bx1+a%by1=gcd(b, a%b);

     根据 gcd(a, b) = gcd (b, a%b);

     ax+by  =  bx1+a%by1;

     a%b = (a- (a/b)*b)

     ax+ by = ay1+ b(x1-(a/b)*by1);

     x=y1; y= x1- a/b*by1;

    这样我们就得到了求解 x, y 的方法:x,y 的值基于 x1,y1.

  上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。

    代码

int exgcd(int a, int b, int &x, int &y) {//x, y表示解 
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  int k = exgcd(b, a%b, x, y);
  int t=x;
  x=y;
  y=t-(a/b)*y;
  return k;
}

   拓展欧几里得的几个应用

   1求解不定方程; 

   例如:求解不定整数方程ax+by = c

     求ax+by = c, 令d =gcd(a,b);

     那么(a / d ) * x + (b / d )* y = c / d

     因为(a / d )、(b / d ) 、x、y都是整数,那么保证原不定整数方程ax+by = c有解的充要条件就是c / d为整数,即c是gcd(a,b)的倍数。

    如果有解,那么令 K = c/d;

    那么,对方程aX+bY = d;假设有拓展欧几里得求出一组解为(X0,Y0),那么aX0+bY0 = d;等式两边同时乘以K,即K*( aX0+bY0 ) = d*K = c;由恒等关系,原方程的解(x0,y0):

    X0 = KX0 = c/d * X0,y0 = KY0 = c/d *Y0。

      不定方程的通解:

       若(x0,y0)是不定整数方程ax+by = c的一组解,则他的任意整数解都可以表示成(x0+ kb’, y0-ka’),其中a’ = a/gcd(a,b), b’ = b/gcd(a,b).

       题目  nyoj1235

        

       a/b%m=k//设等于k

       a/b=k + xm

        a=kb+xmb

       a%m=kb%m+0

      n = kb%m;

      bx+my=gcd(b, m)=1;

      xb%m+my%m=n;

      x=k;

     xb/n%m+my/n%m=1;

    把x/m%m, y.n%m 看成一个整体

     解得 x=k/n;

     k=x*n;

   2求解模线性方程(线性同余方程);

  .......

   3求解模的逆元;

.....

原文地址:https://www.cnblogs.com/a863886199/p/7041873.html