扩展欧几里得算法学习记
话说以前我刷\(noip\)题的时候就想学这个东西了,结果却一直拖到了现在……
到了高二才会这种东西的我实在是个蒟蒻啊!
讲扩展欧几里得算法之前,先讲讲欧几里得算法是什么:\(\gcd(a,b)=\gcd(b,a \bmod b)\)。很显然是不?但我们还是要给出证明(设\(r=a \bmod b\)):
设$x$是$a,b$的一个公约数,由于存在$k=\lfloor\frac{a}{b}\rfloor$使得$a=k*b+r$,又由于$x|a$,$x|b$,则有$x|r$,所以$x$是$b,r$的公约数
设$x$是$b,r$的一个公约数,因为存在$k=\lfloor\frac{a}{b}\rfloor$使得$a=k*b+r$,且$x|b$,$x|r$,那么$x|a$,所以$x$是$a,b$的公约数
综上所述,$a$和$b$的所有公约数 等价于 $b$和$a \bmod b$的所有公约数,于是得证。
所以,扩展欧几里得算法又是什么呢?这个算法就是用来求方程$a*x+b*y=\gcd(a,b)$(令$a,b$为正数)的整数解$x,y$的。
那么,如何求呢?(用到的除号皆为取下整,即$1/3=0$,$6/4=1$)
①显然当$b=0$时有:$x=1,y=0$
②设$r=a \bmod b$,有$r=a-(a/b)*b$
$\because \gcd(a,b)=a*x+b*y=\gcd(b,r) $
又$\because \gcd(b,r)=b*x_1+r*y_1 $
$\begin{aligned} \therefore a*x+b*y &= b*x_1+r*y_1 \\ &= b*x_1+(a-(a/b)*b)*y_1 \\ &= a*y_1+b*(x_1-(a/b)*y_1) \end{aligned}$
$\therefore x=y_1,y=x_1-(a/b)*y_1$
递归地求下去即可
于是我们得到了一组特解$x_0,y_0$,而且满足$|x_0|<b,|y_0|<a$,因此过程中不需要取模
我们假设在$\gcd(b,r)=b*x_1+r*y_1$中满足$|x_1|<r,|y_1|<b$,那么$|x|=|y_1|<b$,$a=r+(a/b)*b$且$|x_1|<r,因此|y|=|x_1-(a/b)*y_1|<a$。
考虑倒数第二步,我们求的是$\gcd(kg,g)$,此时$x=0,y=1$,满足假设条件。因此除了$\gcd(g,0)$这一步之外都满足$|x|<b,|y|<a$。
不难发现其实通解就是 $x=x_0+b/\gcd(a,b)*t,y=y_0-a/\gcd(a,b)*t$
说了这么多,扩展欧几里得算法有什么用呢?写出一长串形如$a*x+b*y=\gcd(a,b)*z$的通解?
其实还可以用来求$a$在$\bmod$ $b$下的乘法逆元$g$(即$a*g \bmod b=1$)
首先这个等式可以写成$a*g+b*x=1$
于是当$\gcd(a,b)\neq1$时该式无解,所以$\gcd(a,b)=1$
于是就变成了拓展欧几里得算法可以求的东西
最后注意$x=x_0+b/\gcd(a,b)*t=x_0+b*t$ 记得把$x$对$b$取模
学了之后才发现这东西和莫队算法一样,是个很简单的东西,几分钟的事