扩展欧几里得算法

     扩展欧几里得(改)

  对于 a 、b 不全为0,存在整数 x 和 y 使得 gcd(a,b)=x*a+y*b ; 整数。。。也就是可以是负的。

  代码:

  
 1 int exGcd(int a,int b,int &x,int &y)
 2 {
 3   if(b==0)
 4   {
 5     x=1;
 6     y=0;
 7     return a;
 8   }
 9   int r=exGcd(b,a%b,x,y);
10   int t=x;
11   x=y;
12   y=t-a/b*y;
13   return r;
14 }
扩展欧几里得算法

  

  首先,我们看一下他是怎么形成的。从最后一层往上推:首先b=0 时得到最大公约数 a ,return a; 现在看上一层,从r那句后继续往下运行,可以知道,此后,每次都从r 句 获得已经得到的最大公约数,然后再往下执行。。。

  规定 a' 、b' 是倒三层的,a、b是倒二层的

  对于倒二层的a、b来说,有gcd(a,b) = x2*a + y2*b ; (x2=0,y2=1,因为这里b就是公约数) 

  对于倒三层的a'、b'来说,gcd(a',b') =  x3*a' + y3*b' ;

  将倒三层的a'和b' 代入倒二层:gcd(a,b) = x2*b' + y2*(a' % b') ;

  ----->因为gcd(a',b') = gcd(a,b)

  ----->所以 x3*a' + y3*b'  =  x2*b' + y2*(a' % b')

  ----->有:x3*a' + y3*b'  =  x2*b' + y2*(a' - a' / b' * b') 【很关键的一步:化解取模】

  ----->整理:x3*a' + y3*b'  =  y2*a' + (x2 - a' / b' * y2)*b' 

  ----->有:x3=y2  、  y3=(x2 - a' / b' * y2)

  ----->两行代码的原因出来了:

  ----->这一层的x等于下一层的y  【就是 x=y; 这一句】

  ----->这一层的y等于下一层的x - a' / b' *y 【就是 y=t-a/b*y; 这一句】

  这里虽然拿特例:倒二倒三层解释,但由于没有涉及具体的x、y值,所以得出的公式应该是通用的。 这解释了我们代码的写法原因,同时最后一层的a本身就是公约数,b为0,所以x1=1;y1=0;

  采用递归写法先到底层,然后由底层的x、y逐步上推,得到顶层的x、y,就是我们想求的x、y。。。

  ......

  注:扩展欧几里得算法可以用于求可逆元等问题中。

 

posted @ 2015-08-06 01:03  hchlqlz  阅读(552)  评论(0编辑  收藏  举报