计算最大公约数和不定方程
•GCD相关性质
性质1.GCD(a,b) = GCD(-a,b) = GCD(a,-b) = GCD( |a| , |b| );
性质2.GCD(a,b) = GCD(a,a-b) = GCD(b,a-b);
性质2推广.GCD(a,b,c) = GCD(a,b-a,c-b) => GCD(a1,a2,...,an) = GCD(a1,a2-a1,...,an-an-1);
性质3.GCD(a,b) = GCD(a%b,a);
性质4.GCD(fib[a],fib[b]) = fib[ GCD(a,b) ];(fib[ i ] : 斐波那契数列的第 i 项)
性质5.GCD(a,b)·LCM(a,b) = a*b;
性质6.设 Gcd(m,a) = 1,则有 Gcd(m,ab) = Gcd(m,b);
这就是说“求 m 与另一个数的最大公约数时,可以把另一个数中与 m 互素的因数去掉”
性质7.设 Gcd(m,a) = 1,那么若 m | ab,则 m | b;
这就是说“若一个数被 m 整除,则把这个数中与 m 互素的因数去掉后仍被 m 整除”。
•与GCD相关的习题
[1]:Codeforces [2]:? [3]:POJ2773
•不定方程
Bezout定理.如果 a,b 都是整数,则 ∃x,y 使得 ax+by = GCD(a,b);
Bezout定理推广.如果 a,b 都是整数,且 GCD(a,b) | c,则 ∃x,y 使得 ax+by = c;
•利用拓展欧几里得算法求解不定方程
由此可知,x1,y1 基于 x2,y2;
一直执行欧几里得算法来到最后一步GCD(0,ai) 的前一步 GCD(ai,bi);
即 ai·xi+bi·yi = GCD(ai,bi) = ai;
所以,此时,满足此式的一个解为 xi=1,yi=0;
然后,根据上述推到的式子,向前回溯,依次求出 (xi-1,yi-1),(xi-2,yi-2),...,(x,y);
如果式子来到 GCD(0,ai) 相当于求出 xi+1=0,yi+1=1;
依次向前求出 (xi=1,yi=0),(xi-1,yi-1),(xi-2,yi-2),...,(x,y);
•extendGCD代码
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 4 /** 5 拓展欧几里得求解 ax+by=GCD(a,b) 的一组解(x,y) 6 */ 7 int extendGCD(int a,int b,int &x,int &y) 8 { 9 if(b%a == 0) 10 { 11 x=1,y=0;///ax+by=a其中的一组解 12 return a; 13 } 14 15 // int gcd=extendGCD(b%a,a,x,y); 16 // int x2=x; 17 // int y2=y; 18 // y=x2; 19 // x=y2-b/a*x2; 20 21 // 15~19可化简为22~23 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相关的习题
[1]:Codeforces