扩展欧几里得算法

资料

  • 欧几里得算法
  • 扩展欧几里得算法
  • 扩展欧几里得算法应用

欧几里得算法

欧几里得算法用于求两个数的最大公约数

证明
设 a > b, a = kb + r;
只需证明gcd( a, b ) = gcd( b, r );
设 gcd( a, b ) = c;
a = m * c, b = n * c;
r = a - kb
  = ( m - nk ) * c;
要证gcd( b, r ) = c;只需证明 ( m - nk ) 与 n 互素,即gcd( m - nk, n ) = 1;
假设gcd( m - nk , n ) = d ( d > 1 );
那么 ( m - n k ) = xd, n = yd;
a = m * c
  = ( xd + nk )c 
  = ( x + ny )cd 
b = ycd;
如果d > 1 那么 gcd( a, b ) >= cd > c; 矛盾
所以 d = 1;
gcd( b, r ) = gcd( a, b );即证
算法
递归版:
int gcd(int a, int b)
{
 return (b == 0 ? a : gcd(b, a % b));
}

非递归版
int gcd( int a, int b )
{
    int t;
    while( b != 0 )
    {
        t = a % b;
        a = b;
        b = t;
    }
    return a;
}

扩展欧几里得算法

在求得a,b 的最大公约数的同时,还能求出一组解x,y,使其满足贝祖等式
ax + by = gcd( a, b )

证明
设 a > b, a = kb + r;
1. b = 0 时,
    gcd( a, b ) = a,x = 1,y = 0;
2. b != 0 时,
   设 ax1 + by1 = gcd( a, b );
       bx2  + ( a % b )y2 = gcd( b, a % b );
   由欧几里得算法得
   ax1 + by1 = bx2 + ( a % b )y2;
   化简得
   x1 = y2;
   y1 = x2 -( a / b )y2;
   上述表明x1, y1 可由 x2, y2表示,以此递归下去,直到b = 0;可知必有解,
   即证.
算法
递归版
int exgcd(int a,int b,int & x,int & y){
    if(b == 0){
        //根据上面的推理1,基本情况
        x = 1;
        y = 0;
        return a;
    }
    //根据推理2
    int r = exgcd(b, a%b, x, y);
    int t = y;
    y = x - (a/b)*y;
    x = t;
    return r;
}

非递归版
int exgcd(int a,int b,int &x,int &y)
{
    int r = a % b;
    int x0, y0, x1, y1;
    x0 = 1; y0 = 0;
    x1 = 0; y1 = 1;
    x  = x1; y  = y1;
    while( r )
    {
        x = x0 -  a/b * x1;
        y = y0 -  a/b * y1;
        x0 = x1;
        y0 = y1;
        x1 = x;
        y1 = y;
        a = b;
        b = r;
        r = a % b;
    }
    return b;
}
非递归算法证明
根据欧几里得算法
a = bq1 + r1; (1)
b = r1q2 + r2;(2)
r1 = r2q3 + r3;
....
ri-2 = ri-1*qi + r i;
....
rn-2 = rn-1*qn + rn; 
rn-1 = rn*qn+1 + 0;
因为对于ri>0,ri均是gcd(a, b)的倍数
所以每一步均存在 xi, yi, 使得 a xi + b yi = ri成立
ri = ri-2 - ri-1*qi
   = ( a*xi-2 + b*yi-2 ) - ( a*xi-1 + b*yi-1 )*qi
   = a*( xi-2 - qi*xi-1 ) + b( yi-2 - qi*yi-1 )
因为 ri = a xi + b yi;
xi = xi-2 - qi*xi-1;
yi = yi-2 - qi*yi-1;
直到求xn, yn;
因为 (1)和(2)式,
初始化 x0 = 1,y0 =0,x1=0,y1=1;

扩展欧几里得算法应用

  • 求解不定方程
  • 求解模线性方程
  • 求解模的逆元
求解不定方程

不定方程指ax + by = c,
a,b,c是整数,证明ax+by=c在整数范围内有解的充要条件是 gcd( a, b )整除c.

证明:
设gcd( a,b )= d,则 d|c ,c = kd;
充分性:
ax0 + by0 = d,左右乘k,即可证明
必要性:
ax0 + by0 = c; d|a, b|a,那么 d|ax0 + by0,则 d|c即证  
算法
bool linear_equation(int a,int b,int c,int &x,int &y)
{
    int d=exgcd(a,b,x,y);
    if(c%d)
        return false;
    int k=c/d;
    x*=k; y*=k;    //求得的只是其中一组解
    return true;
}
求解模线性方程

模线性方程是指 ax≡b (mod n)

求解:
ax≡b(mod n)  等价于 ax = b + nk;
等价于 ax + ny = b;
当b|gcd( a, n )时,有解
设 gcd( a,n ) = d, ax0 + ny0 = d,
那么存在解 x = x0 * ( b/d ); 对模n有特解 x = x0*(b/d)( mod n );
易知,x, y有多解  
由x = ( b/a ) + ( n / a ) * y知,x的相邻解的间隔时相同的
设间隔为dx
ax≡b(mod n) 
a(x+ dx) ≡b(mod n) 
相减  adx ≡ 0 ( mod n )  即 n | adx,且 a | adx.
那么最小的dx满足 
adx = lcm( a, n )
       = a n / gcd( a, n )  
 dx = n / d;
可知,该方程对模n恰有d个不同的解(这个很显然,但不会理论证明)
算法
bool modular_linear_equation(int a,int b,int n)
{
    int x,y,x0,i;
    int d=exgcd(a,n,x,y);
    if(b%d)
        return false;
    x0=x*(b/d)%n;   //特解
    for(i=1;i
求解模的逆元

ax≡ 1 (mod n), gcd( a, n ) = 1, 只有唯一解,该解称为 x 为 a 的对模 n 乘法的逆元。

扩展欧几里得算法_第1张图片
byene.jpg

你可能感兴趣的:(扩展欧几里得算法)