扩展欧几里德算法

  本文章可以算是http://www.cnblogs.com/yylogo/archive/2011/06/06/SGU-106.html文章的子文章吧,剖析里面的扩展欧几里德。
  首先要了解欧几里德公式。

  题目里用到的定理大概有下面几个:

  1. 对于等式ax+by=c,a,b,c皆为整数,c如果是gcd(a, b)的倍数,则方程有解,否则方程误解。
      这一个的证明省略,我也不会。
  2. 因为等式ax+by=gcd(a, b)必定有解(定理1),所以可以解出来,解法如下:
      因为gcd(a, b) = gcd(b, a % b),所以有bx1+(a%b)y1=gcd(a,b),注意!此时x1并不等于x,y1也不等于y!这个过程可以循环(就想求最大公约数一样),将b视为新的a',a%b视为新的b',可以得到b'x2+(a'%b')y2=gcd(a,b)一直到b''''(n个')=0时,等式就变成:a''..'xn+0y=gcd(a,b),此时根据辗转相除法gcd(a, b)就应该等于a''...',所以xn = 1, yn = 任意数,取0就好。
      然后根据ax+by=bx1+(a%b)y1 => ax+by=bx1+(a-a/b*b)y1 => ax+by=ay1+b(x1+a/b*y1) 根据恒等定理得x=y1,y=(x1+a/b*y1),接着……递归吧。
      也不知道解释清楚没有,没看懂的去http://baike.baidu.com/view/1478219.htm看看。
  3. 对于等式ax+by=c,abc皆为整数且c是gcd(a, b)的倍数,且(x1, y1)是方程ax+by=gcd(a, b)一组整数解,则(x1*(c/gcd(a, b)), y1*(c/gcd(a, b)))是方程ax+by=c的一组解
      证明简易,省略……
  4. 对于等式ax+by=c,abc皆为整数且c是gcd(a, b)的倍数,且(x1, y1)是方程一组整数解,那么方程的所有整数解为:x=x1+k*(b/gcd(a,b)),y=y1+k*(a/gcd(a,b)),k是任意整数,对于一组x, y,k相同。
      因为(x1, y1)是原方程的一组解,所以有ax1+by1=c,则易得a(x1+k*b)+b(y1-k*a)=c,但是x每增加b,y就会减少a,是否有更小的范围,设d是a,b的约数,但不是最大公约数(若最大公约数是1则d=1)易得a(x1+k*(b/d))+b(y1-k*(a/d))=c,可以知道增加量变小了,现在要求什么时候最小,当然是分母最大的时候变化值最小,也就是当x1+b/gcd(a,b),就是x1的下一个整数解!
      不知道解释清楚没有,没看懂的去http://www.cppblog.com/willing/archive/2011/01/10/114115.html看看,他那解释了一下,但感觉太简略了。
posted @ 2011-06-09 15:08  zqynux  阅读(1560)  评论(0编辑  收藏  举报