1. 程式人生 > >歐幾里得及擴充套件歐幾里得(應用:求解不定方程、解模線性方程、求模的逆元)

歐幾里得及擴充套件歐幾里得(應用:求解不定方程、解模線性方程、求模的逆元)

歐幾里得

1.含義:歐幾里德演算法又稱輾轉相除法,用於計算兩個整數a,b的最大公約數。

原理公式:gcd(a,b)=gcd(b,a mod b)

因此(a,b)(b,a mod b)的公約數是一樣的,其最大公約數也必然相等.

2.實現:

int gcd(int a,int b)
{

    return b?gcd(b,a%b):a;

}

擴充套件歐幾里得

1. 含義:對於不完全為 0 的非負整數 a,b,gcd(a,b)表示a,b 的最大公約數,必然存在整數對 x,y ,使得 gcd(a,b)=ax+by。

2.結果:得到(a,b)最大公約數d,同時得到一組 整數解x、y。

3.實現:

(遞迴)

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 temp=x;
    x=y;
    y=temp-a/b*y;
    return d;
}

(迭代)

int exgcd(int m,int n,int &x,int &y)
{
    int x1,y1,x0,y0;
    x0=1; y0=0;
    x1=0; y1=1;
    x=0; y=1;
    int r=m%n;
    int q=(m-r)/n;
    while(r)
    {
        x=x0-q*x1; y=y0-q*y1;
        x0=x1; y0=y1;
        x1=x; y1=y;
        m=n; n=r; r=m%n;
        q=(m-r)/n;
    }
    return n;
}

4.應用

<1>求解不定方程

形如:ax+by=c      a、b、c已知,求一組 整數x、y使得方程成立。

解:由上述<實現>程式碼可得  最大公約數d=gcd(a,b)、一組x0、y0;(此x、y是方程ax+by=gcd(a,b)的解)

①方程ax+by=gcd(a,b) 的通解:x=x0+b/d*k;y=y0-a/d*k ; (k為任意常數,下同)

②方程ax+by=c的通解:x=x0*c/d+b/d*k ;  y=y0*c/d-a/d*k ;

另:判斷是否有解的方法  :  c%d=0 則有解,否則反之。

<2>求解模線性方程

模線性方程 : ax≡b(mod m)

     其中a,b和m是已知的(m>0),要求解出滿足上式的對模m的x值。滿足同餘方程的x可能有多個,也可能一個都沒有,上述模線性方程也稱為一次同餘方程。

    解:模線性方程ax≡b(mod m)的步驟如下:

(1)求 d=gcd(a,m)

(2)若d%b!=0,則ax≡b(mod m)無解;否則有解(且有d個解)

(3)求x0,y0,是a*x0+m*y0=d;

(4)由於d是b的因數,將a*x0+m*y0=d改寫,得a(x0*(b/d))+m*(y0*(b/d))=b, 

         於是ax+my=b的一個特解為 x=x0*(b/d),y=y0*(b/d);

(5)x0*(b/d)是ax≡(mod m)的一個特解,由此的ax≡b(mod m)的所有解

       (共d個)為:x= (x0*(b/d)+ i*(m/d) ) (mod m),    i=0,1,2,3,4.……d-1

<3>用歐幾里德演算法求模的逆元:

       同餘方程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 。