intexgcd(int a,int b,int &x,int &y) { if(b == 0) { x = 1; y = 0; return a; } int gcdd = exgcd(b,a%b,x,y); int t = x; x = y; y = t - (a/b)*y; return gcdd; }
我们可以看出,y = t - (a/b)*y 中,t是上次的y,y是上次的x,所以可以简化一下
1 2
int gcdd = exgcd(b,a%b,y,x); y-=(a/b)*x;
扩展欧几里得的用途
求解形如 ax +by = c 的通解,但是一般没有谁会无聊到让你写出一串通解出来,都是让你在通解中选出一些特殊的解,比如一个数对于另一个数的乘法逆元。
intexgcd(int a,int b,int &x,int &y) { if(b == 0) { x = 1; y = 0; return a; } int gcdd = exgcd(b,a%b,x,y); int t = x; x = y; y = t - (a/b)*y; return gcdd; }
intmove_reverse(int a,int b) { int d, x, y; d = exgcd(a, b, x, y); if(d != 1) return-1; else return (x%b+b)%b; }
intmain() { int a, b; cin >> a >> b; cout << move_reverse(a, b) << endl; return0; }
intexgcd(int a,int b,int &x,int &y) { if(b == 0) { x = 1; y = 0; return a; } int gcdd = exgcd(b,a%b,x,y); int t = x; x = y; y = t - (a/b)*y; return gcdd; }
voidCongruenceEquation(int a, int b, int c) { int x; int y; int d = exgcd(a, b, x, y); if(c % d != 0) return; //求出x推y x = c * x / d;//乘c除以d得到方程的一个解 int t = b / d; int min_x = (x % t + t) % t; int min_y = (c / d - (a / d) * min_x) / (b / d); cout << min_x << " " << abs(min_y) << endl; //求出y推x y = c * y / d; t = a / d; min_y = (y % t + t) % t; min_x = (c / d - (b / d) * min_y) / (a / d); cout << abs(min_x) << " " << min_y << endl; }
intmain() { //(a*x)%b=n //a*x=n (mod b) //a*x+b*y=c int a,b,c; cin >> a >> b >> c; CongruenceEquation(a, b, c); return0; }