欧几里德及其拓展和应用
- 欧几里德定理求最大公约数:
Datatype Gcd(Datatype a, Datatype b){ return (b == 0 ? a : Gcd (b, a%b)); }
运用的原理为辗转相除
Gcd(a, b) == Gcd (b, a) == Gcd(-a, b) == Gcd(|a|, |b|)
- 拓展欧几里得定理:
求解方程ax + by = Gcd(a, b);
int Gcd_value = 0, x = 0, y = 0; //Gcd_value为a,b的最大公约数 int exGcd(int a, int b, int &Gcd_value, int &x, int &Y){ if (b == 0){ x = 1; y = 0; Gcd_value = a; } else{ exGcd(b, a%b, Gcd_value, x, y); int temp = x; x = y; y = tm - y*(a/b); } }
证明:
当a != 0且b == 0,Gcd(a, b) = a,则ax + by = a ==> x = 1且y =0;
当a*b!= 0时,Gcd(a, b) == Gcd (b, a%b);
则有 ax1 + by1 = Gcd(a, b) = Gcd (b, a%b) = bx2 + (a%b)y2;
将右边变形:b*x2 + (a%b)*y2 = b*x2 + (a –[a/b]*b)*y2 = b*x2 + a*y2 – b*y2*[a/b] = a*y2 + b*(x2 - y2*[a/b]);
则有 ax1 + by1 = a*y2 + b*(x2 - y2*[a/b]) ==> x1 = y2 且 y1 = x2 - y2*[a/b];
故采用递归的方法直到找到 b==0 时的情况,即 xn = 1 且 yn = 0,然后回溯赋值给xn-1,yn-1,然后继续回溯......直到找到x0,y0 !
此时就有 a*x0 + b*y0 = Gcd(a, b) ==> a*(x0 + T*b) + b(y0 - T*a) = Gcd(a, b);
则有 通解 x = x0 + T*b,y = y0 - T*a(T为任意整数,即 ····,-2,-1,0,1,2,······);
- 运用拓展欧几里德求解 ax + by = c:
首先有如下结论,(我不知道怎么来的)
若 ax + by = c 有解 则 c%Gcd(a, b) == 0 否则 方程无解;
下面求解:
上面我们得到了 ax + by = Gcd(a, b) 的初始解,x0和y0;
设 p = c/Gcd(a, b) => c = p*Gcd(a, b);
联立方程: a*x + b*y = Gcd(a, b) 与 a*xx + b*yy = c = p*Gcd(a, b);
则可得 a*(xx/p) + b*(yy/p) = Gcd(a, b) 则可推出通解:
xx = x*p = x*c/Gcd(a, b);
yy = y*p = y*c/Gcd(a, b);
- 运用拓展欧几里德求乘法逆元: