扩展欧几里得算法学习笔记

  扩展欧几里得算法是用来求解类似于: ${ax+by=gcd(a,b)}$在${mod~n}$意义下的不定方程的解${x,y}$的算法。

  这鬼里鬼气的算法我学了很久,一直都是似懂非懂,只知道写代码而不知道其精髓,在膜拜了网上无数的博客后终于是明白了。

  我们用扩展欧几里得算法来计算形如:${ax+by=c}$的不定方程的${x}$和${y}$。

  我们都知道可以用欧几里得算法求解${gcd(a,b)}$,也就是${gcd(a,b)=gcd(b,a\%b)}$,而扩展欧几里得算法就是基于它来进行计算的。

  我们先考虑如何求解${ax+by=gcd(a,b)}$。$$ax+by=gcd(a,b)=gcd(b,a\% b)$$

$$bx'+(a\% b)y'=gcd(b,a\% b)$$

$$ax+by=bx'+(a\% b)y'$$

$$ax+by=bx'+(a-\lfloor a/b \rfloor*b)y'$$

$$ax+by=ay'+b(x'-\lfloor a/b \rfloor *y')$$

$$\therefore x=y',y=x'-\lfloor a/b \rfloor *y'$$

  因为${gcd(a,b)}$在${b=0}$时就会回溯出解,所以我们可以递归求解${ax+by=gcd(a,b)}$,复杂度$lg~n$。

  接下来进入正题,如何求解:${ax+by=c}$。$$ax+by=c$$

$$ax'+by'=gcd(a,b)=d$$

  我们${ax+by=c}$两边同除${d}$:$$\frac{a}{d}x+\frac{b}{d}y=\frac{c}{d}$$

  由于${d=gcd(a,b)}$,所以${a/d}$和${b/d}$都是整数,若${c}$不能整除${d}$的话,那么方程无解。

  将2式两边同时乘上${c/d}$,将右侧的${d}$化为${c}$: $$a*\frac{c}{d}*x'+b*\frac{c}{d}*y'=c$$

  于是我们就求出了${x}$和${y}$的一组解(注意这里的${x_0}$和${y_0}$都有可能是$<0$的):$$x_0=\frac{c}{d}*x',y_0=\frac{c}{d}*y'$$

  可是对于一些数论问题,它会要求求出的${x}$的最小的正整数,这怎么办呢。我们先将${x}$和${y}$的解集求出来,还是上面那个式子,两边同时除以${c}$:$$\frac{a}{d}*x'+\frac{b}{d}*y'=1$$

  在这里我们引入一个变量${k}$,原式可以写成:$$(x'+k*\frac{b}{d})*\frac{a}{d}+(y'-k*\frac{a}{d})*\frac{b}{d}=1$$

  这样做有什么好处呢,其实我们已经可以表示出${x,y}$的通解了,将方程两边同时乘上${c}$:$$x=(x'+k*\frac{b}{d})*\frac{c}{d},y=(y'-k*\frac{a}{d})*\frac{c}{d}$$

  将${x}$变形一下:

\begin{aligned}  x&=(x'~mod~\frac{b}{d}+\frac{b}{d}*\lfloor\frac{x'}{b/d}\rfloor+k*\frac{b}{d})*\frac{c}{d}  \\  &=\lgroup x'~mod~\frac{b}{d}+\frac{b}{d}*(k+\lfloor\frac{x'}{b/d}\rfloor)\rgroup*\frac{c}{d}  \end{aligned}

  因为${b/d}$为正数,所以里面的值随着${k}$的增大而增大,所以我们不妨令:$$k=-\lfloor \frac{x'}{b/d} \rfloor$$

  这样一来,求出来的${x}$就是最小正整数了:$$x=(x'~mod~\frac{b}{d})*\frac{c}{d}$$

  因为${x’}$求出来可能是负的所以最后还要做点处理,${x}$最后的的表达式:$$x=(x'*\frac{c}{d}\%\frac{b}{d}+\frac{b}{d})\%\frac{b}{d}$$

posted @ 2016-09-27 15:26  MashiroSky  阅读(992)  评论(3编辑  收藏  举报