资料链接:例题 详解
//求最大公约数gcd(a,b) int gcd(int a,int b) { return !b?a:gcd(b,a%b); } //最小公倍数lcm(a,b) int lcm(int a,int b) { return a*b/gcd(a,b); } //扩展欧几里得算法:求线性方程ax+by=gcd(a,b) int ex_gcd(int a,int b,int& x,int& y) { if(b==0) { x=1,y=0; return a; } int g=ex_gcd(b,a%b,x,y);//g为最大公约数 int tmp=x; x=y; y=tmp-a/b*y; return g; } //若求ax+by=m,m|gcd(a,b), //先求ax0+by0=gcd(a,b),x=x0*m/gcd(a,b),y=y0*m/gcd(a,b); //若ax0+by0=gcd(a,b); //任意解为x=x0+b/gcd(a,b)*t,y=y0-a/gcd(a,b)*t;结论1:
根据上面的讨论,方程a * x - n * y = 1要有解,1必须是gcd(a, n)的倍数,因此a与n必须互素(即gcd(a, n) = 1)。所以当gcd(a, n) = 1时,该方程有解,否则方程无解。
void egcd(LL a, LL b, LL &x, LL &y, LL &G) { if(!b) { G = a; x = 1; y = 0; } else { egcd(b, a%b, y, x, G); y -= x*(a/b); } }
egcd(a, M, x, y, G); return G == 1? (x+M)%M: -1LL;