扩展GCD的一点心得
ex_gcd是用于直接求解ax+by=gcd(a,b)的
首先给代码吧,
int ex_gcd(int a,int b,int& x,int& y)//求解Ax+By=gcd(A,B); { if(b==0)//递归至b为0时,a此时为gcd(A,B)的值,当然x=1,y=0是此时的解; { x = 1; y = 0; return a; } int d = ex_gcd(b,a%b,x,y); int t = x; x = y; y = t - a/b*y; return d; }
由朴素gcd的思想,当b=0时,a就是gcd的值,那么此时x = 1,y = 0;是一组解
关于b!=0的一般情况,假设ax1+by1=gcd(a,b)(1),a’x2+b’y2=gcd(a’,b’)(2)
都满足等式左侧第二项前的系数不为0,且(2)是(1)的下一次递归调用,就有a’=b,b’=a%b=a-a/b*b;
(2)可以带入整理得到ay2+bx2-(a/b)*by2= gcd(b,a%b)(3)
由于gcd的性质,gcd(a,b) = gcd(b,a%b),联立(1),(3),解得x1 = y2,y1 = (x1 - a/b*y2);
对于求解任意一组解ax+by=gcd(a,b)已经完成,在求解ax+by=c的一组解情况在下面求解ax+by=c的全部解得最前面有讲,不赘述了。
对于求解全部ax + by = c的解:
首先肯定就是求解ax + by = gcd(a,b)(我们求的解设为x0,y0),观察c能否整除gcd(a,b),不能就无解,能就有解。
不妨来一波基操(骚操作)
a*x0+lcm(a,b)+b*y0-lcm(a,b)=gcd(a,b);
ax +by =gcd(a,b);
由于(lcm(a,b)*gcd(a,b)=a,b)
一般解x = x0 + b/gcd(a,b),y = y0 - a/gcd(a,b);
那么回到ax + by = c;
x = c/gcd(a,b)*x0 + b/gcd(a,b)*t;
y = c/gcd(a,b)*y0 - a/gcd(a,b)*t;(t取整数)