扩展欧几里得算法公式快速推导
主要用于以后复习查阅。
求特解
由辗转相除法(欧几里得算法)可得 \(\gcd(a,b)=\gcd(b,a \bmod b)\)
由裴蜀定理,存在 \(x,y\) 使得 \(xa+yb=\gcd(a,b)\),存在 \(x',y'\) 使得 \(x'b+y'(a \bmod b)=\gcd(b,a \bmod b)\)
所以 \(xa+yb = x'b+y'(a \bmod b)\)
又因为 \(a \bmod b\) 可以写成 \(a - \left\lfloor \dfrac{a}{b} \right\rfloor \times b\)
所以 \(xa+yb = x'b + y' \left( a - \left\lfloor \dfrac{a}{b} \right\rfloor \times b \right)\)
转化右式,\(xa+yb = y'a + \left( x'- \left\lfloor \dfrac{a}{b} \right\rfloor \times y' \right) b\)
这样,左右式就变成了同一个形式,在每次进行辗转相除返回时时令:
其中 \(x',y'\) 分别表示后面递归返回的 \(x,y\)。
当 \(b=0\) 时,因为 \(a+b=a=\gcd(a,0)=\gcd(a,b)\),所以此时 \(x=1,y=1\)。
模板代码:
int exgcd(int a,int b,int &x,int &y)
{
if(b)
{
int res=exgcd(b,a%b,x,y);
int x_=x;
x=y,y=(x_-(a/b)*y);
return res;
}
else
{
x=1,y=1;
return a;
}
}
求通解
解不定方程 \(xa+yb=c\)
设 \(d=\gcd(a,b)\),则有 \(xa+yb=d\),用上面的 exgcd
求出一组特解为 \(x_0,y_0\),那么有 \(x_0 a + y_0 b = d\)
左式可以转化:
\( \begin{aligned} & x_0 a + y_0 b\\ =& x_0 a + kab + y_0 b - kab\\ =& (x_0+kb)a+(y_0+ka)b = d \end{aligned} \)
两边同乘 \(\dfrac{c}{d}\),注意这时如果 \(c\) 不整除于 \(d\),那么方程无解。
\(\left( \dfrac{c}{d} \cdot x_0 + k \cdot \dfrac{b \cdot c}{d} \right)a + \left( \dfrac{c}{d} \cdot y_0 + k \cdot \dfrac{a \cdot c}{d} \right)b = c\)
因为 \(\dfrac{c}{d}\) 是整数,所以其可以并入到 \(k\) 里去,设 \(k' = k \times \dfrac{c}{d}\),则:
\(\left( \dfrac{c}{d} \cdot x_0 + k' \cdot \dfrac{b}{d} \right)a + \left( \dfrac{c}{d} \cdot y_0 + k' \cdot \dfrac{a}{d} \right)b = c\)
其中 \(k'\) 可以等于任意整数,这样就求出了方程的通解:
可以通过将 \(x\) 对 \(\dfrac{b}{d}\) 取模,将 \(y\) 对 \(\dfrac{a}{d}\) 取模的方式来取得最小解。
注意在上述内容在代码实现过程中随时可能出现负数,别忘了先加再取模。
本文采用 「CC-BY-NC 4.0」 创作共享协议,转载请注明作者及出处,禁止商业使用。
作者:Jerrycyx,原文链接:https://www.cnblogs.com/jerrycyx/p/18503201