欧几里得+拓展欧几里得

(1)知识支持:

  定理1:

    Gcd(a,b) = Gcd(-a,b) = Gcd(a,-b) = Gcd( |a| , |b| )。

  定理5:

    设 Gcd(m,a) = 1,则有 Gcd(m,ab) = Gcd(m,b),这就是说“求 m 与另一个数的最大公约数时,可以把另一个数中与 m 互素的因数去掉”。

  定理6:

    设 Gcd(m,a) = 1,那么若 m | ab,则 m | b,这就是说“若一个数被 m 整除,则把这个数中与 m 互素的因数去掉后仍被 m 整除”。

  定理7:

    Lcm(a,b)*Gcd(a,b) = |ab|。

 

 

 


(2)欧几里得算法:

  欧几里得算法是用来求 a 和 b 的最大公公约数(Greatest Common Divisor)的算法。

  那么由欧几里得算法可得:

    Gcd(a,b) = Gcd(b%a , a);

证明欧几里得算法正确性的关键是证明 Gcd(a,b)=Gcd(b%a,a);
令x=Gcd(a,b),y=Gcd(b%a,a);
b%a可表示为a和b的线性组合:b%a=b-(b/a)*a;
因为 a%x=0,b%x=0;
所以 (b%a)%x=0;
故y%x=0;
又(b%a)%y=[b-(b/a)*a]%y=0,a%y=0;
根据同余定理可得
b%y-(b/a)*a%y=0,所以b%y=(b/a)*a%y=0;
所以x%y=0;
所以Gcd(a,b)=Gcd(b%a,a);
证毕;
证明

 


 (2)拓展欧几里得算法:

  线性组合定义:

    如果 a 和 b 都是整数,则 ax+by 是 a 和 b 的线性组合,其中 x,y 为整数。

  定理1:

    设 c 是 a 和 b 的线性组合中的最小正整数,即 ax+by = c,(x,y为整数)。

    则 c = Gcd(a,b);

   定理1证明:

   

  定理2:

    如果 a 和 b 都是整数,则存在整数 x,y 使得 ax+by = Gcd(a,b);

  推论:

    整数 a 和 b 互素,当且仅当存在 x,y 使得 ax+by = 1;

 

  给出不定方程 ax+by = Gcd(a,b) ,拓展欧几里得算法可以用于求解不等方程组的整数根(x,y)。

  拓展欧几里得算法:

  

 1 /**
 2     求解满足ax+by=Gcd(a,b)的所有解(x,y)
 3 */
 4 #include<iostream>
 5 #include<cstdio>
 6 using namespace std;
 7 
 8 int extendGcd(int a,int b,int &x,int &y)
 9 {
10     if(a == 0)
11     {
12         x=0,y=1;
13         return b;
14     }
15 
16     int gcd=extendGcd(b%a,a,x,y);
17     int x2=x,y2=y;
18     y=x2;
19     x=y2-b/a*x2;
20 
21 //    第16~19可简化为
22 //    int gcd=extendGcd(b%a,a,y,x);
23 //    x -= b/a*y;
24 
25     return gcd;
26 }
27 int main()
28 {
29     int a,b;
30     while(~scanf("%d%d",&a,&b))
31     {
32         int x,y;
33         int gcd=extendGcd(a,b,x,y);
34         printf("%d*%d+%d*%d=%d\n",a,x,b,y,gcd);
35     }
36 }
extendGcd模板

  定理3:

    方程 ax+by = c 有解的充要条件是 Gcd(a,b) | c,当 ax+by = c 有解时,他的解和方程

    的解相同。

    假设 (x0,y0)是 ax+by = c 的一组解,那么 ax+by = c 的所有整数解为:(k为整数)

    x = x0+k×[ b/Gcd(a,b) ];

    y = y0-k×[ a/Gcd(a,b) ];

posted @ 2019-01-25 23:00  HHHyacinth  阅读(216)  评论(0编辑  收藏  举报