「欧几里得与扩展欧几里得算法」学习笔记
$$y-=x*(a/b)$$
$$(c/g(x_0+k*b/g),c/g(y_0-k*a/g))$$
欧几里得算法
\(gcd(a, b)\) 表示 \(a,b\) 的最大公约数。
欧几里得辗转相除法:
$gcd(0,a) = a$
$gcd(a,b) = gcd(b, a \ mod\ b), b > 0$
算法证明
设 $ a = bq + r $,则需证明的是 $ gcd(a,b) = gcd(b, r) $
可以通过证明$ (a,b) $的任何公因子必定也是$ (b,r) $的公因子,且$ (b,r) $的任何公因子必定也是$ (a,b) $的公因子
设\(d\)为\(a, b\)的任意一个约数 $ (d > 0)$,则有\(d|a, d|b\)。可以设\(a = sd, b = td\) (\(s, t\) 为整数)
∴ \(r = a - bq = sd - tdq = d(s - tq)\) ∴ \(d|r\)
故$ (a,b) $的所有约数都是\( (b,r)\)的约数。
可再次证明\( (b,r) \)的所有约数都是\( (a,b)\)的约数。
故 $ gcd(a,b) = gcd(b, r) $
扩展欧几里得算法 EXGCD
Exgcd用来求解方程:$ ax + by = gcd(a,b) $ (关于解的存在性证明可参见 贝祖定理 )
很明显该方程的解不止一个。先考虑解出一组特解
求解过程
特殊的,当$b = 0$时,$gcd(a,b) = a$,故解得$x = 1, y = 0$
一般的,设:$$ \begin{cases} ax_1 + by_1 = gcd(a,b) \\ bx_2 + (a\%b)y_2 = gcd(b,a\%b) \end{cases} $$
由欧几里得算法可得$gcd(a,b) = gcd(b, a\%b)$,因此:$$ ax_1 + by_1 = bx_2 + (a\%b)y_2 $$$$ = bx_2 + (a - \left \lfloor a / b \right \rfloor*b)y_2 $$$$ = bx_2 + ay_2 - \left \lfloor a / b \right \rfloor*by_2 $$$$ = ay_2 + b(x_2 - \left \lfloor a / b \right \rfloor y_2) $$
因此$$ax_1 + by_1 = ay_2 + b(x_2 - \left \lfloor a / b \right \rfloor y_2)$$
由恒等式的性质可得一组特解:$$ \begin{cases} x_1 = y_2 \\ y_1 = x_2 - \left \lfloor a / b \right \rfloor * y_2 \end{cases} $$
因此倒推即可
void exgcd(int a, int b, int &g, int &x, int &y){ if(!b){ g = a; x = 1, y = 0; return; } exgcd(b,a%b,g,y,x); y -= x*(a/b); }
通解求法
设$ k_1 = \left \lfloor a / gcd(a,b) \right \rfloor , k_2 = \left \lfloor b / gcd(a,b) \right \rfloor$ 。$k_1, k_2$一定互质
同时除以$gcd(a,b)$,得$ax / gcd(a,b) + by / gcd(a,b) = 1$,即$ k_1x + k_2y = 1 $
要求得通解,并使等式仍然成立,\(x, y\)不可能同时变大或变小,不然等号不能成立。故\(x, y\)的大小变化相反。
设\(x\)增大\(d_1\),\(y\)减小\(d_2\), 可得\(a(x + d_1) + b(y - d_2) = gcd(a, b)\)
通解即为\( (x + k * d_1, y - k * d_2) \) (k为常数,且为整数)
与前面的做法相同,两边同时除以\(gcd(a,b)\),可得$$a(x + d_1) / gcd(a,b) + b(y - d_2) / gcd(a,b) = 1$$
即$$k_1(x + d_1) + k_2(y - d_2) = 1$$
由于$k_1x + k_2y = 1$, 两边同时减去1, 得$$k_1d_1 = k_2d_2$$
由于\(k_1, k_2\)互质,故\(d_1, d_2\)一定可以满足$$k_1 = d_2, k_2 = d_1$$
因此代入可得$$a(x + k_2) + b(y - k_1) = gcd(a, b)$$
因此通解为$$ (x + k * k_2, y - k * k_1) $$
故解得通解为$$ (x + k * \left \lfloor b / gcd(a,b) \right \rfloor, y - k * \left \lfloor a / gcd(a,b) \right \rfloor) $$
求解线性不定方程
求解$ax + by = c$
当$gcd(a,b) | c$时方程一定有解,否则无解
在方程 $ax_0 + by_0 = gcd(a,b) $ 两边同时乘以 $c / gcd(a,b)$ 可得 $ ax_0 * c / gcd(a,b) + by_0 * c / gcd(a,b) = c $
在\(a, b\)的值并没有改变的情况下,原方程的解就是:$$ \begin{cases} x = x_0 * c / gcd(a,b) \\ y = y_0 * c / gcd(a,b) \end{cases} $$
关于最小正整数解
由于$x$的通解是$x + k * b / gcd(a,b)$,因此最小正整数解为$x \ mod \ (b / gcd(a,b))$。前提是保证$b / gcd(a,b) > 0$。而会出现$b / gcd(a,b) < 0$的情况只有$a,b$同负或$b$为负数,因此特判$b$的正负即可
注意当$x<0$时模一遍仍然为负数,所以需要模两遍:$$x' = (x \ mod \ (b / gcd(a,b)) + (b / gcd(a,b)) \ mod \ (b / gcd(a,b)$$
求解线性同余方程
形如\(ax≡b\ (mod\ m)\)
由原方程\(ax≡b\ (mod\ m)\)很容易推得\( ax - b \) 是\(m\)的倍数。不妨设\(ax - b\)是\(m\)的\(y\)倍。则有方程$ ax - b = my $
移项即可得$ ax - my = b $ 求不定方程即可