歐幾里得算法與擴展歐幾里得算法_C++

先感謝參考文獻:http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.htmlhtml

注:如下討論的數均爲整數算法

 

1、歐幾里得算法(重點是證實,對後續知識有用)spa

  歐幾里得算法,也叫展轉相除,簡稱 gcd,用於計算兩個整數的最大公約數code

  定義 gcd(a,b) 爲整數 a 與 b 的最大公約數htm

  引理:gcd(a,b)=gcd(b,a%b)blog

  證實:遞歸

    設 r=a%b , c=gcd(a,b)get

    則 a=xc , b=yc , 其中x , y互質模板

    r=a%b=a-pb=xc-pyc=(x-py)cclass

    而b=yc

    可知:y 與 x-py 互質

    證實:

                假設 y 與 x-py 不互質

                設 y=nk , x-py=mk , 且 k>1 (由於互質)

                將 y 帶入可得

                x-pnk=mk

                x=(pn+m)k

                則 a=xc=(pn+m)kc , b=yc=nkc

                那麼此時 a 與 b 的最大公約數爲 kc 不爲 k

                與原命題矛盾,則 y 與 x-py 互質

    由於 y 與 x-py 互質,因此 r 與 b 的最大公約數爲 c

    即 gcd(b,r)=c=gcd(a,b)

    得證

  當a%b=0時,gcd(a,b)=b

  這樣咱們能夠寫成遞歸形式

1 inline int gcd(int a,int b)
2 {
3     return b?gcd(b,a%b):a;
4 }

 

  模板題:http://codevs.cn/problem/1212/ 

 

2、擴展歐幾里得算法

   擴展歐幾里得算法,簡稱 exgcd,通常用來求解不定方程,求解線性同餘方程,求解模的逆元等

  引理:存在 x , y 使得 gcd(a,b)=ax+by

  證實:

         當 b=0 時,gcd(a,b)=a,此時 x=1 , y=0

         當 b!=0 時,

         設 ax1+by1=gcd(a,b)=gcd(b,a%b)=bx2+(a%b)y2

         又因 a%b=a-a/b*b

         則 ax1+by1=bx2+(a-a/b*b)y2

    ax1+by1=bx2+ay2-a/b*by2

    ax1+by1=ay2+bx2-b*a/b*y2

    ax1+by1=ay2+b(x2-a/b*y2)

    解得 x1=y2 , y1=x2-a/b*y2

    由於當 b=0 時存在 x , y 爲最後一組解

    而每一組的解可根據後一組獲得

    因此第一組的解 x , y 必然存在

    得證

  根據上面的證實,在實現的時候採用遞歸作法

  先遞歸進入下一層,等到到達最後一層即 b=0 時就返回x=1 , y=0

  再根據 x=y’ , y=x’-a/b/y’ ( x’ 與 y’ 爲下一層的 x 與 y ) 獲得當層的解

  不斷算出當層的解並返回,最終返回至第一層,獲得原解

 1 inline void exgcd(int a,int b)
 2 {
 3     if (b)
 4         {
 5             exgcd(b,a%b);
 6             int k=x;
 7             x=y;
 8             y=k-a/b*y;
 9         }
10     else y=(x=1)-1;
11 }

 

 

 

3、exgcd 解不定方程(使用不將a與b轉爲互質的方法)

  對於 ax+by=c 的不定方程,設 r=gcd(a,b)

  當 c%r!=0 時無整數解

  當 c%r=0 時,將方程右邊 *r/c 後轉換爲 ax+by=r 的形式

  能夠根據擴展歐幾里得算法求得一組整數解 x0 , y0

  而這只是轉換後的方程的解,原方程的一組解應再 *c/r 轉變回去

  (如 2x+4y=4 轉換爲 2x+4y=2 後應再將解得的 x , y 乘上2)

  則原方程解爲 x1=x0*c/r , y1=x0*c/r

  通解 x=x1+b/r*t , y=y1-a/r*t ,其中 t 爲整數

  證實:

    將 x , y 帶入方程得

    ax+ab/r*t+by-ab/r*t=c

    ax+by=c

    此等式恆成立

    得證

  這裏 b/r 與 a/r 爲最小的係數,因此求得的解是最多最全面的

  證實:

    爲了推出證實中的 ax+by=c ,且想達到更小的係數,只能將 b/r 與 a/r 同除以一個數 s

    而 b/r 與 a/r 互質,且 s 爲整數,則 s=1 ,不影響通解

    那麼 b/r 與 a/r 就爲最小的係數

    得證

 

  模板題:http://www.cnblogs.com/hadilo/p/5917173.html

 

 

4、exgcd 解線性同餘方程

  關於 x 的模方程 ax%b=c 的解

  方程轉換爲 ax+by=c 其中 y 通常爲非正整數

  則問題變爲用 exgcd 解不定方程

  解得 x1=x0*c/r

  通解爲 x=x1+b/r*t

  設 s=b/r (已證實 b/r 爲通解的最小間隔)

  則 x 的最小正整數解爲 (x1%s+s)%s

  證實:

    若 x1>0,則 (x1%s+s)%s=x1%s%s+s%s=x1%s=x1-ts (t∈N)

    若 x1<0,因在 C++ 裏 a%b=-(-a%b)<0 (a<0 , b>0)  如 -10%4=-2

         則 (x1%s+s)%s=(-(-x1%s)+s)%s=(-(ts-x1)+s)%s=ts-x1 (t∈N)

    即爲 x1 經過加或減上若干個 s 後獲得的最小正整數解

    得證

  亦可僞證 x1<0 的狀況:設 x1=-5 , s=2

              則 (x1%s+s)%s=(-5%2+2)%2=(-1+2)%2=3%2=1

              即爲 x1 加上 3 個 s 後的到的最小正整數解

 

  模板題:http://www.cnblogs.com/hadilo/p/5951091.html

 

 

 

 

版權全部,轉載請聯繫做者,違者必究

聯繫方式:http://www.cnblogs.com/hadilo/p/5932395.html

相關文章
相關標籤/搜索