一、欧几里得算法
欧几里得算法,也叫辗转相除法,简称 gcd,用于计算两个整数的最大公约数
引理 :欧几里得有个非常强的定理,gcd(a,b)=gcd(b,a mod b)。
这里就不证明了,代数书上有简洁优美的证明。
二、扩展欧几里得算法
扩展欧几里得算法,简称 exgcd,一般用来求解不定方程,求解线性同余方程,求解模的逆元等。
(在此顺便简介一下乘法逆元: 若有 a * x ≡ 1 (mod m),则称 x 为a关于m的乘法逆元,等价式 a * x + m * y = 1)
引理:存在 x , y 使得 gcd(a,b)=ax+by
证明:
当 b=0 时,
gcd(a,b) = a,此时 x = 1, y = 0。
当 b != 0 时,
设 ax1+by1 = gcd(a,b) = gcd(b,a%b) = bx2 + (a%b)y2,
又因 a%b = a-a / b * b,
则 ax1+by1 = bx2+(a - a / b * b)y2,
ax1+by1 = bx2 + ay2- a / b * by2,
ax1+by1 = ay2+bx2-b * a / b * y2,
ax1+by1 = ay2+b(x2- a / b * y2),
解得 x1 = y2 , y1 = x2 - a / b * y2。
因为当 b=0 时存在 x , y 为最后一组解,而每一组的解可根据后一组得到,所以第一组的解 x , y 必然存在,得证。
三、exgcd 解不定方程(不将a与b转为互质)
对于 ax+by = c 的不定方程,设 r = gcd(a,b)。
当 c%r != 0 时,无整数解。
当 c%r = 0 时,将方程右边 * r / c 后转换为 ax+by=r 的形式,可以根据扩展欧几里得算法求得一组整数解 x0 , y0,而这只是转换后的方程的解,原方程的一组解应再 * c / r 转变回去则原方程解为 x1 = x0 * c / r , y1 = y0 * c / r,通解 x = x1 + b / r * t , y = y1 - a / r * t ,其中 t 为整数。
四、exgcd 解线性同余方程
关于 x 的模方程 ax % b = c 的解,方程转换为 ax+by = c 其中 y 一般为非正整数,则问题变为用 exgcd 解不定方程,解得 x1 = x0 * c / r,通解为 x = x1+b / r * t,设 s = b / r (b / r为通解的最小间隔),则 x 的最小正整数解为 (x1 % s + s) % s。
//exgcd的一种写法
#include <iostream>
long long exgcd(long long a, long long b, long long &x, long long &y)
{
if(a == 0 && b == 0)
return -1;
if(b == 0)
{
x = 1;
y = 0;
return a;
}
long long d = exgcd(b, a%b, y, x);
y -= a/b*x;
return d;
}
五、类欧几里得
参照 https://coding.oi-wiki.org/math/euclidean/ (这个坑以后再填)