1 void gcd(LL a,LL b,LL &d,LL &x,LL &y){ 2 if(b==0){d=a;x=1;y=0;return;} 3 gcd(b,a%b,d,x,y); 4 int t=x; 5 x=y; 6 y=t-a/b*x; 7 return; 8 } 9 LL t(LL a,LL b,LL c,LL &x,LL &y ){//解ax+by=c的方程 10 LL d;gcd(a,b,d,x,y); 11 if(c%d)return -1;//c%gcd(a,b)若不为0,则无解 12 //将x调成最小正整数,下面顺序不能乱 13 LL ran=b/d; 14 if(ran<0)ran=-ran; 15 x*=c/d; 16 x=(x%ran+ran)%ran; 17 return 0; 18 }
成功get一套解拓展欧几里得方程的完全代码;
总体来说,解这种方程有以下几个步骤:
1.用ex_gcd求出一对x0,y0;
2.用x0,y0推出符合条件的一组解;
详细:
理论求解顺序:
原方程ax+by=c; 1
计算方程:ax+by=gcd(a,b) 2
化简方程:a'x+b'y=1;a'=a/gcd(a,b),b'=b/gcd(a,b); 3
2式,3式等价,用ex_gcd算哪个都行;
ex_gcd解方程;
得到一组解:x0,y0
x0*=c/gcd(a,b),y0*=c/gcd(a,b);
现在x0,y0是ax+by=c的一组解;
由此可推出通解:x0+kb',y0-ka',注意这里k后面的是b',a';
虽然用a,b直接推出来的解也是对的,但是会忽略掉一些解,如果在一些对解有特殊要求的题目中的话,可能会wa;