扩展欧几里得 [FINISHED]

1 算法定义:  给定两个数$a,b$,设$Gcd(a,b)=d$,则存在整数$x,y$,使得$x*a+y*b=d$。扩展欧几里得算法可以计算出$x,y$

2 算法实现:  $Gcd(a,b)=Gcd(b,a\ mod \ b)$.因此,假设$bx+(a\ mod \ b)y=d$,即$bx+(a-\left \lfloor \frac{a}{b} \right \rfloor*b)y=d$,所以:$ay+b*(x-\left \lfloor \frac{a}{b} \right \rfloor*y)=d$.

template <typename INT_TYPE,
          typename = std::enable_if_t<std::is_integral<INT_TYPE>::value>>
INT_TYPE EXGcd(INT_TYPE a, INT_TYPE b, INT_TYPE &x, INT_TYPE &y) {
  if (0 == b) {
    x = 1;
    y = 0;
    return a;
  }
  INT_TYPE d = EXGcd(b, a % b, x, y);
  INT_TYPE t = x;
  x = y;
  y = t - a / b * y;
  return d;
}  

 

这个程序返回值为$Gcd(a,b),ax+by=Gcd(a,b)$,其中$x,y$分别存在$x,y$中。

当然,如果给出的是求ax+by=c,这时当且仅当Gcd(a,b)可以整除c时x,y有整数解。这个很好证明,设Gcd(a,b)=d,那么a=d*k1,b=d*k2,所以ax+by=d*(k1*x+k2*y),即ax+by必为d的倍数,所以c必为d的倍数,即d必能整除c。这样的话,先求ax+by=d的一组解x0,y0,设k=c/d,则k*x0,k*y0就是一组解。

 

3 其他应用:  扩展欧几里得可以求乘法逆元。乘法逆元的意思就是对于a,p,若存在b使得ab%p=1,则称b为a对p的乘法逆元. 对于一个数x,x/a%p=x*b%p(a可以整除x)。这样的话,就可以将除法变为乘法.

  (1) 证明: 设x=k*a,则x/a%p=k%p=(k%p)*(ab%p)=(k*a*b)%p=x*b%p。

  (2) 计算$b$: ab%p=1,我们可得ab=kp+1(k为某个整数),即ab-kp=1,令x=b,y=-k,则我们求出ax+py=1的一组解x,y即可。这个式子有解的充要条件是Gcd(a,p)=1.

posted @ 2013-11-27 23:37  朝拜明天19891101  阅读(464)  评论(0编辑  收藏  举报