Exgcd 扩展欧几里得算法
引入
有时我们需要求解关于 \(x,y\) 的方程 \(a\times x+b\times y=\gcd(a,b)\)。
这需要扩展欧几里得算法。
Exgcd
对于方程
\[ a\times x+b\times y=\gcd(a,b)\tag{1}
\]
一般地,有
\[ \gcd(a,b)=\gcd(b,a\bmod b)\tag{2}
\]
可参考我的这篇博文。
将 \((2)\) 代入 \((1)\),得
\[a\times x+b\times y=\gcd(b,a\bmod b)\tag{3}
\]
再将 \((1)\) 代入 \((3)\),得(记 \(\left\lfloor\cfrac{a}{b}\right\rfloor=a\div b\))
\[\begin{aligned}
a\times x+b\times y&=b\times x+(a\bmod b)\times y\\
&=b\times x+(a-\left\lfloor\cfrac{a}{b}\right\rfloor\times b)\times y\\
&=b\times x+a\times y-a\div b\times b\times y\\
&=a\times y+b\times (x-a\div b\times y)\\
\end{aligned}
\]
即
\[a\times x+b\times y=a\times y+b\times (x-a\div b\times y)\tag{4}
\]
整理得
\[\begin{cases}
\begin{cases}
x=1\\
y=0
\end{cases}& b=0
\\\\
\begin{cases}
x=y'\\
y=x'-a\div b\times y'
\end{cases}& \text{otherwise}
\end{cases}
\tag{5}
\]
其中 \(x',y'\) 为递归求解 \(\gcd(b,a\bmod b)\) 所得的结果。
于是得到代码。
代码
void exgcd(int a,int b,int &x,int &y)
{
if(!b){x=1,y=0;return;}
exgcd(b,a%b,y,x),y-=a/b*x;return;
}
应用
求解线性同余方程
形如
\[ax\equiv b\pmod n\tag{1}
\]
的方程叫做线性同余方程。
首先,我们可以将其改写为这样的线性不定方程:
\[ax+nk=b\tag{2}
\]
显然我们可以通过调整 \(k\),使代入 \(x\) 时等式成立。也就是说 \(x,k\) 都是未知数。
考虑先使用 exgcd 求解如下方程:
\[ax'+nk'=\gcd(a,n)\tag{3}
\]
对 \((3)\) 变形,两边同除以 \(\gcd(a,n)\),同乘以 \(b\):
\[a\left(x'\times\cfrac{b}{\gcd(a,n)}\right)+n\left(k'\times\cfrac{b}{\gcd(a,n)}\right)=b\tag{4}
\]
于是可以得到方程 \((2)\) 的解:
\[\begin{cases}
x=\cfrac{bx'}{\gcd(a,n)}\\
k=\cfrac{bk'}{\gcd(a,n)}
\end{cases}
\]
其中 \(x\) 也是方程 \((1)\) 的解。
求逆元
逆元即一个特殊线性同余方程的解:
\[ax\equiv 1\iff x\equiv a^{-1}\pmod n
\]
显然可以用 exgcd 解决。
\[x=\cfrac{x'}{\gcd(a,n)}
\]
特别地,当 \(a<n\land n\in\Bbb{P}\)(\(n\) 为大质数)时,
\[x=x'
\]
直接使用 exgcd 即可。
注意,以上问题判断无解时需要判断解中的除法是否整除。