参考资料:
1.https://www.bilibili.com/video/BV1x3411s7Sy/?spm_id_from=333.788&vd_source=e66dd25b0246f28e772d75f11c80f03c
2.余红兵:《数学奥林匹克小丛书(第二版)高中卷10————数论》
最大公约数
设a,b∈Z,如果d∈Z且d∣a,d∣b,则称d是a和b的公因子(公约数)。
若d≥0,且a和b的所有公因子都整除d,则称d是a和b的最大公约数,记作gcd(a,b)。
之前CSDN上我也写过一篇gcd筛:
https://blog.csdn.net/hustle28214/article/details/128601837?spm=1001.2014.3001.5501
设a,b∈Z,若gcd(a,b)=1,则称a和b互素。
互素的a,b公因子仅有±1,该条件可反推出a,b两数互素。
根据定义有结论:
设gcd(a,b)=d,则存在q1,q2∈Z,使得a=q1d,b=q2d,且gcd(q1,q2)=1。
若gcd(q1,q2)=t>1,则gcd(a,b)=td>d,与“最大”矛盾。
欧几里得算法(辗转相除法)
设a≥b≥0,求gcd(a,b)
对于上述条件下的a,b,有a=qb+r;
b=0时,gcd(a,0)=a
b>0时,gcd(a,b)=gcd(b,r)=gcd(r1,r2)
gcd(a,b)=gcd(b,r)这条推广有必要演示一下:
gcd(40,3)=1
gcd(40,3)=gcd(3,1)=gcd(1,0)=1
依次如此操作直到见到0
int gcd(int x, int y)
{
int r = x % y;
while (r != 0)
{
x = y;
y = r;
r = x % y;
}
return y;//最大公约数实现
}
扩展欧几里得算法
(重要)定理5-1(最大公约数表示定理)(裴蜀定理)
设a,b∈Z,d=gcd(a,b),则存在s,t∈Z,使得as+bt=d。
特别地:gcd(a,b)=1 ———— as+bd=1(充要)
推论:d∣v ———— as+bt=v
证明:
设b≥a,b=ax1+r1,那么b后b=r1。
重复辗转相除直至余数为0。
b=ax1+r1,
a=r1x2+r2,
......,
rk−3=rk−2xk−1+rk−1 (2)
rk−2=rk−1xk+rk,(1)
rk−1=rkxk+1+rk+1。
此时rk+1=0(余数)。由此得出rk=d(最大公约数)。将此式代入(1)式,移项得到d=rk−2−rk−1xk。
将此式与(2)式联立,得到d=rk−2−(rk−3−rk−2xk−1)xk。
展开,得到d=m1rk−2−n1rk−3。
上述所有提及皆为整数,则m1(1−xk−1xk),n1(−xk)必为整数。
相同的操作可以重复做,不断带入之前的式子可以发现最后可以化成d=mka+nkb。
而显然mk,nk为整数。
证毕。
对于第二条“特别地”的证明如下:
假设gcd(a,b)=1。
那么,将a表示为k1gcd(a,b)=a,b=k2gcd(a,b)。
代入as+bd=1:k1gcd(a,b)s+k2gcd(a,b)r=1。
即,(k1s+k2r)=1/gcd(a,b)
那么右式取值区间为(0,1),显然无法满足整数解性质。
所以gcd(a,b)=1才能使as+bd=1有整数解。
想一想,如果要证其必要性,则假设as+bd=1没有整数解,右式=1,也必定存在s,d∈Z使得方程有解。
第三条推论自不必说,v是d的整数倍。
所以,扩欧相对于欧几里得算法的扩展性就是:使用欧几里得算法时,利用余数和商向上迭代出sn,tn。这同样也是在计算二元一次不定方程。
通过扩欧我们可以找到判断二元一次不定方程是否有整数 解的方法:
对于方程ax+by=z,只有满足gcd(a,b)∣z,方程才有整数解。
最小公倍数
设a,b∈Z,若m∈Z分别是a和b的倍数,m称为a和b的公倍数。
记a,b的最小公倍数为lcm(a,b),若m是a和b所有正的公倍数中最小,m称作a和b的最小公倍数。
lcm(a,b)=gcd(a,b)ab。
我在CSDN那篇上写“最小公倍数的求算依赖于最大公约数的求算”,其实这有些以偏概全,求最小公倍数的算法并不止这一种。下面就记录一下这种不需要找最大公约数的神奇算法(更相增益术/更相减损术):
设有两正整数0\<a\<b。
a更小,a自加成2a;此时若发现b更小,b自加,成2b;...;若发现a更小,a自加,直到2ka=2k−1b。那么2ka就等于lcm(a,b)。
int lcm(int a,int b)
{
while(a!=b)
{
if(a\<b)
a+=a;
else if(b\<a)
b+=b;
}
return a;
}