拓展gcd求不定方程通解

 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 }
View Code

成功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;

posted @ 2016-10-09 17:21  CHADLZX  阅读(224)  评论(0编辑  收藏  举报