总结——数论:欧几里得算法&扩展欧几里得

一 欧几里得辗转相除法算法

  设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),又因 r = a mod b,所以 gcd(a,b)=gcd(b,a mod b)

  证明:①证明充分性。

    设 d 为 a,b 的公约数,记作 d|a , d|b ,即a和b都可以被d整除

    又因 r=a-kb , 两边同时除以d,r/d=a/d-kb/d=m,由等式右边可知m为整数, d|r , 即 d 是 (b,a mod b)的公约数,

    ②证明必要性

    设 d 为 b, a mod b 的公约数,则 d|b , d|r

    又因 a=r+kb ,所以 d 为 a 的因子,即 d|a ,因此 d 是 a,b 的公约数。

    综上,(a,b) 和 (b,a mod b) 的公约数一样,其最大公约数必然相等。

 

二 扩展欧几里得算法

  如果 gcd(a,b)=d , 那么一定存在整数 x,y 满足 ax+by=d.

  求出 x,y 的值就表示定理成立。注意因为这是一个不定方程,所以解不只有一组。如果大家有相关证明可以留言讨论。x,y 值的求解:

    设存在 ax+by=gcd(a,b)

    根据欧几里得定理 gcd(a,b)=gcdb,mod b) ,

    可得 ax+bgcd(a,bgcd(b,mod bbx+(mod b)y′ = bx+(ab∗[a/b])y′ = ay' +b(x' - [a/b]y')

    由恒等定理可知,x=y' 
            y=x' - [a/b] y'

  可以看到,x,y 的值由 x',y' 得出。而 x',y' 又如何得到?递归。

  重新来看看我们得到的两个等式。x 和 y 是 gcd(a,b)=ax+b的解,而 x’ 和 y’ 是在对 gcd(a,b按欧几里德算法进行一步后的结果对应的贝祖等式 gcd(b,mod b)=bx+(mod b)y′ 的解。也就是说,gcd(a,b对应的贝祖等式的解 x,y 可以由 gcd(b,mod b对应等式的解x’,y’计算得出。

  由于欧几里德算法最后一步为 gcd(d,0)=d,此时对应等式存在解 x=1,y=0, 因此只要如上述代码,从 gcd(d,0往前处理,在进行欧几里德算法的递归的时候根据相邻两次调用间 x,y 和 x’,y’ 的关系计算即可求出 ax+by=gcd(a,b的解。

  方程通解:若(a,b)=1,且x0,y0为a*x+b*y=n的一组解,则该方程的任一解可表示为:x=x0+b*t,y=y0-a*t;且对任一整数t,皆成立。

 

三 扩展欧几里得算法的应用

  ①求解不定方程

    pa+qb=c的整数解,只需将p * a+q * b = Gcd(p, q)的每个解乘上 c/Gcd(p, q) 即可。

    有整数解的条件:c|gcd(p,d)。

 

  ②求解模线性方程(线性同余方程)ax≡b (mod n) 的最小解

    同余方程 ax≡b (mod n)对于未知数 x 有解,当且仅当 gcd(a,n) | b。且方程有解时,方程有 gcd(a,n) 个解。

    求解方程 ax≡b (mod n) 相当于求解方程 ax+ ny= b(x, y为整数)

    设 ax+ny=gcd(a,n) 的解为 x0,y0,则 ax+ny=b 的解为 x=x0*b/gcd(a,n)

    要求其最小整数解,可根据同解x = x0 + n/gcd(a,n) * t;

    设 s = n / gcd(a,n),x%s得到最一个值x1,x1可能为负数,此时x%s还需要+s,加上s后可能就不是最小值了,所以还需要在对s取余

    所以最小(整数)解为 x = (x % s + s) % s

 

  ③求解模的逆元

    同余方程ax≡b (mod n),如果 gcd(a,n)== 1,则方程只有唯一解。在这种情况下,如果 b== 1,同余方程就是 ax=1 (mod n ),gcd(a,n)= 1。这时称求出的 x 为 a 的对模 n 乘法的逆元。

        对于同余方程 ax= 1(mod n ), gcd(a,n)= 1 的求解就是求解方程 ax+ ny= 1,x, y 为整数。这个可用扩展欧几里德算法求出,原同余方程的唯一解就是用扩展欧几里德算法得出的 x 。

 

求 gcd(a,b) 的代码:

//递归
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);        
}

//迭代
int Gcd(int a, int b){
    while(b != 0){
      int r = b;
      b = a % b;
      a = r;
    }
    return a;
}

 

求解 ax+by=gcd(a,b)=d 的解 x,y 的代码如下:

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

 

posted @ 2018-02-18 00:12  Travelller  阅读(374)  评论(0)    收藏  举报