昨天做了一道题,发现我对扩展欧几里得理解的还不够透彻。
下面来说说扩展欧几里得。
Ax+By+C=0;那么我们求解这个方程,我们可以将C移到方程右边那Ax+By=-C;
然后我们先分析下A,B的符号,那么如果A=0,那么By=-C;直接求解,如果B能够整除C的话,那么Y=-C/B;那么x可以取任意整数值,同理当B=0时,那么当A=B=0时,C=0,那么x,y取任意的值,当C不为0则无解。
下面来说下扩展欧几里得 的算法原理:
我们求解 ax+by=gcd(a,b);这里我们假定a>0&&b>0; 那么由欧几里的求最大公约数可以知道gcd(a,b)=gcd(b,a%b);
那么我们可以写得方程a‘x’+b‘y’=gcd(a‘,b‘);这里我们设a’=b;b‘=a%b;那么这两个方程是等价的可以写成
ax+by=a‘x‘+b‘y‘;那么a%b=a-b×(a/b);那么ax+by=bx‘+(a-b×(a/b))×y‘;那么合并一下ax+by=ay‘+b(x‘-(a/b)y‘);
那么可以得到x=y’,y=x‘-(a/b)y‘;最后我们可以的到a×1+b×0=a=gcd(a,b);我习惯于先求a/(gcd(a,b))x+b/(gcd(a,b))=1的解;
然后ax+by=-C×(a/(gcd(a,b))x+b/(gcd(a,b)));然后的x=-C/gcd(a,b)x;y=-C/gcd(a,b)*y;最后通解为x+t×/gcd(a,b);y-t*gcd(a,b);
1 LL gcd(LL n,LL m) 2 { 3 if(m==0) 4 { 5 return n; 6 } 7 else if(n%m==0) 8 { 9 return m; 10 } 11 else return gcd(m,n%m); 12 } 13 pair<LL,LL>P(LL n,LL m) 14 { 15 if(m==0) 16 { 17 pair<LL,LL>ask=make_pair(1,0); 18 return ask; 19 } 20 else 21 { 22 pair<LL,LL>an=P(m,n%m); 23 LL x=an.second; 24 LL y=an.first; 25 y-=(n/m)*x; 26 an.first=x; 27 an.second=y; 28 return an; 29 } 30 }
假如A*B>0;1.(a<0)那么方程可以变为abs(A)x+abs(B)y=C;然后用扩展欧几里得求解即可;
那么这样假设我们要求解在某个范围内的x,和某个范围内的y,这样的解有多少组时,那么我们先求出特解,然后二分t的值,同时二分y中t的值,这样求两个t的重合处就为组数。
假如A*B<0,如果A<0的时候我们改变方程得abs(A)x+abs(B)y=C;我们先解得特解x1,y1;而原方程为abs(A)x-By=C;-By=B(y1)那么特解y=-y1;这时abs(A)(x1+B*t)-B(-y1+abs(A)t);那么这时和上面一样二分找t就行。
假如A*B<0,如果A>0;那么abs(A)x+abs(B)y=-C;解得特解x1,y1;原方程为abs(A)x-abs(B)y=-C;那么特解y=-y1;这时abs(A)(x1+B*t)-abs(B)(-y1+abs(A)t);
下面给个很好的题的连接http://www.cnblogs.com/zzuli2sjy/p/5583123.html