欧几里得算法&扩展欧几里得算法&线性同余方程学习笔记

本文详细介绍了欧几里得算法及其扩展形式,用于计算最大公约数(GCD)和解决线性同余方程。通过递归原理,展示了算法如何高效地找到两个数的最大公约数,并进一步推广到多个数的最大公约数。扩展欧几里得算法不仅用于求GCD,还能求解模线性方程,确保解的性质。当GCD整除给定值时,存在无限多解;否则,无解。算法复杂度为O(log n),适用于各种数值计算问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、最大公约数

一组整数的公约数,是指能够同时整除这组数中每一个数的整数。
一组整数的最大公约数(Greatest Common Divisor,GCD),是指这组数所有公约数中最大的一个。
例如, 6,12,18,30,526, 12, 18, 30, 526,12,18,30,52 的最大公约数是 222

二、欧几里得算法

下面的式子是欧几里得算法的核心:
gcd⁡(a,b)=gcd⁡(b,a mod b)\gcd(a,b) = \gcd(b, a \bmod b)gcd(a,b)=gcd(b,amodb)

接下来给出证明:
a,ba,ba,b 的公约数必然为 b,a mod bb, a \bmod bb,amodb 的公约数。
ddda,ba,ba,b 的公约数,a=kb+ca=kb+ca=kb+c,则 d∣a,d∣bd \mid a, d \mid bda,db,则 a mod b=ca \bmod b = camodb=c,由于 d∣a,d∣(kb)d \mid a, d \mid (kb)da,d(kb),故 d∣cd \mid cdc ,因此 d∣(a mod b)d \mid (a \bmod b)d(amodb),又因为 d∣bd \mid bdb,所以 a,ba,ba,b 的公约数必然为 b,a mod bb, a\bmod bb,amodb 的公约数。
b,a mod bb, a \bmod bb,amodb 的公约数必然为 a,ba,ba,b 的公约数。
dddb,a mod bb, a\bmod bb,amodb 的公约数,a=kb+ca=kb+ca=kb+cd∣b,d∣(a mod b)d \mid b, d\mid (a\bmod b)db,d(amodb) ,则 a mod b=ca \bmod b=camodb=c,由于 d∣(kb),d∣cd \mid (kb), d \mid cd(kb),dc,故 d∣ad \mid ada,又因为 d∣bd \mid bdb,所以 b,a mod bb, a\bmod bb,amodb 的公约数必然为 a,ba, ba,b 的公约数。

由①②得,a,ba,ba,b 的公约数和 b,a mod bb, a\bmod bb,amodb 的公约数完全相同,因此,它们的最大公约数也相同,即 gcd⁡(a,b)=gcd⁡(b,a mod b)\gcd(a,b)=\gcd(b, a\bmod b)gcd(a,b)=gcd(b,amodb)

在计算两个数的最大公约数时,可以根据这个等式,不断递归,直到 b=0b=0b=0 。代码如下。

int gcd(int a, int b){
	return b == 0 ? a : gcd(b, a % b);
}

递归过程中 a mod ba \bmod bamodb 至少将 aaa 的规模减半,所以递归层数为 log⁡n\log nlogn 层,复杂度为 O(log⁡n)O(\log n)O(logn)

三、多个数的最大公约数

计算多个整数的最大公约数时可以根据:
gcd⁡(a1,a2,a3,...,an)=gcd⁡(gcd(a1,a2),a3,a4,...,an)\gcd(a_1,a_2,a_3,...,a_n)=\gcd(gcd(a_1,a_2), a_3,a_4,...,a_n)gcd(a1,a2,a3,...,an)=gcd(gcd(a1,a2),a3,a4,...,an)

不断减少数字的个数,最终简化成两个整数的情况。

四、扩展欧几里得算法

扩展欧几里得算法常用于求解类似 ax+by=gcd(a,b)ax+by=gcd(a,b)ax+by=gcd(a,b) 形式的二元一次方程组的一组可行解。
顾名思义,扩展欧几里得算法与欧几里得算法有相似之处,其实,这两种算法都使用了 gcd⁡(a,b)=gcd⁡(b,a mod b)\gcd(a,b) = \gcd(b, a\bmod b)gcd(a,b)=gcd(b,amodb) 这条性质不断缩小问题规模,而后回溯求解。因此,不妨构造一个与 ax+by=gcd⁡(a,b)ax+by=\gcd(a,b)ax+by=gcd(a,b) (以下称作方程①) 类似的方程 bx+(a mod b)y=gcd⁡(b,a mod b)bx+(a\bmod b)y = \gcd(b, a\bmod b)bx+(amodb)y=gcd(b,amodb) (以下称作方程②) 并且假设已知后面方程组的一组解为 x=x0,y=y0x=x_0, y=y_0x=x0,y=y0。因此有:
ax+by=gcd⁡(a,b)=gcd⁡(b,a mod b)=bx0+(a mod b)y0ax+by=\gcd(a,b)=\gcd(b, a\bmod b)=bx_0+(a\bmod b)y_0ax+by=gcd(a,b)=gcd(b,amodb)=bx0+(amodb)y0

ax+by=bx0+(a−⌊ab⌋×b)y0ax+by=bx_0+(a-\lfloor\frac{a}{b}\rfloor\times b)y_0ax+by=bx0+(aba×b)y0

a(x−y0)+b(y−x0+⌊ab⌋y0)=0a(x-y_0)+b(y-x_0+\lfloor\frac{a}{b}\rfloor y_0)=0a(xy0)+b(yx0+bay0)=0

故可以得到原方程的解为 x=y0,y=x0−⌊ab⌋y0x=y_0,y=x_0-\lfloor\frac{a}{b}\rfloor y_0x=y0,y=x0bay0。这样,在得知方程②解的情况下可以推得方程①的解。那么如何求出方程②的解呢?
通过观察两个方程的系数可以发现,从① →\rarr ②的过程中,系数会通过取模减小的,那么同欧几里得算法一样,不断递归,使系数减小,直到 b=0b=0b=0 ,此时根据欧几里得算法有 a=gcd⁡(a,b)a=\gcd(a,b)a=gcd(a,b),求出此时方程 gcd⁡(a,b)x+0y=gcd⁡(a,b)\gcd(a,b)x + 0y=\gcd(a,b)gcd(a,b)x+0y=gcd(a,b) 的解为 x=1,yx=1,yx=1,y 为任意值,不妨设 y=0y=0y=0,不断回溯得到原方程 ax+by=gcd⁡(a,b)ax+by=\gcd(a,b)ax+by=gcd(a,b) 的解。代码如下:

// 其中 d 为最大公约数,可以不写,将 exgcd 函数定义为 void 类型
int exgcd(int a, int b, int &x, int &y){
	if (!b){
		x = 1, y = 0;
		return a;
	}
	int d = exgcd(b, a % b, x, y);
	int tmp = x;
	x = y;
	y = tmp - (a / b) * y;
	return d;
}

递归过程同欧几里得算法,因此复杂度也为 O(log⁡n)O(\log n)O(logn)

五、扩展欧几里得算法求出的特解性质

使用扩展欧几里得算法求出的特解 x=x0,y=y0x=x_0, y=y_0x=x0,y=y0 满足性质 ∣x0∣<b,∣y0∣<a| x_0 | < b, | y_0 | < ax0<b,y0<a 。采用归纳法证明如下:
不妨假设共进行 nnn 层递归,原方程为 ax+by=gcd⁡(a,b)ax+by=\gcd(a,b)ax+by=gcd(a,b),第 iii 层递归得到的方程为 aix+biy=gcd⁡(a,b)a_ix+b_iy=\gcd(a,b)aix+biy=gcd(a,b),该层递归得到的解为 x=xi,y=yix=x_i, y=y_ix=xi,y=yi ,递归出口 anx+bny=gcd⁡(a,b)a_nx+b_ny=\gcd(a,b)anx+bny=gcd(a,b),其中 bn=0b_n=0bn=0
① 当 gcd⁡(a,b)=bi\gcd(a,b)=b_igcd(a,b)=bi 时:
a mod b=0a \bmod b = 0amodb=0,因此递归层数 i=n−1i=n-1i=n1 ,得到解为 x=xn−1=1,y=yn−1=0x=x_{n-1}=1, y=y_{n-1}=0x=xn1=1,y=yn1=0,此时满足∣xn−1∣<∣bn−1∣,∣yn−1∣<∣an−1∣| x_{n-1} | < |b_{n-1}|, |y_{n-1}| < |a_{n-1}|xn1<bn1,yn1<an1
② 当 gcd⁡(a,b)≠bi\gcd(a,b) \neq b_igcd(a,b)=bi 时:
不妨假设第 i+1i+1i+1 层递归得到的解 x=xi+1,y=yi+1x=x_{i+1}, y=y_{i+1}x=xi+1,y=yi+1 满足 ∣xi+1∣<∣bi+1∣,∣yi+1∣<∣ai+1∣| x_{i+1} | < | b_{i+1} |, | y_{i+1} | < | a_{i+1} |xi+1<bi+1,yi+1<ai+1 。根据系数递归的公式有 ai+1=bi,bi+1=ai mod bia_{i+1} = b_i, b_{i+1} = a_i\bmod b_iai+1=bi,bi+1=aimodbi
则对于 xix_ixi
∣xi∣=∣yi+1∣<∣ai+1∣=∣bi∣| x_i | = | y_{i+1} | < | a_{i+1} | = | b_i |xi=yi+1<ai+1=bi

对于 yiy_iyi
∣yi∣=∣xi+1−⌊aibi⌋yi+1∣⩽∣xi+1∣+∣⌊aibi⌋yi+1∣=∣xi+1∣+⌊aibi⌋∣yi+1∣⩽∣bi+1∣−⌊aibi⌋∣yi+1∣| y_i | = | x_{i+1} - \lfloor \frac{a_i}{b_i} \rfloor y_{i+1} | \leqslant | x_{i+1} | + | \lfloor \frac{a_i}{b_i} \rfloor y_{i+1} | = | x_{i+1} | + \lfloor\frac{a_i}{b_i}\rfloor | y_{i+1} | \leqslant | b_{i+1} | - \lfloor\frac{a_i}{b_i}\rfloor | y_{i+1} |yi=xi+1biaiyi+1xi+1+biaiyi+1=xi+1+biaiyi+1bi+1biaiyi+1

⩽ai mod bi+⌊aibi⌋∣yi+1∣⩽ai−⌊aibi⌋bi+⌊aibi⌋∣yi+1∣⩽ai−⌊aibi⌋(bi−∣yi+1∣) \leqslant a_i \bmod b_i + \lfloor\frac{a_i}{b_i}\rfloor | y_{i+1} | \leqslant a_i - \lfloor\frac{a_i}{b_i}\rfloor b_i + \lfloor\frac{a_i}{b_i}\rfloor | y_{i+1} | \leqslant a_i - \lfloor\frac{a_i}{b_i}\rfloor(b_i-|y_{i+1}|)aimodbi+biaiyi+1aibiaibi+biaiyi+1aibiai(biyi+1)

又因为 ∣yi+1∣<∣ai+1∣=∣bi∣|y_{i+1}| < |a_{i+1}|=|b_i|yi+1<ai+1=bi ,所以 bi−∣yi+1∣>0b_i - | y_{i+1} | > 0biyi+1>0,故 ∣yi∣<∣ai∣| y_i | < |a_i|yi<ai ,满足性质。
根据数学归纳法可得,原方程的解亦满足性质。

六、求解二元一次方程不定方程

接下来我们要求解二元一次方程 ax+by=cax+by=cax+by=c
gcd⁡(a,b)∣c\gcd(a,b) \mid cgcd(a,b)c 时,有无穷多组解。
使用扩展欧几里得算法求出方程 ax+by=gcd⁡(a,b)ax+by=\gcd(a,b)ax+by=gcd(a,b) 的特解 x=x0,y=y0x=x_0, y=y_0x=x0,y=y0 后,方程 ax+by=cax+by=cax+by=c 的一组特解可以表示为:
x=cgcd⁡(a,b)x0,y=cgcd⁡(a,b)y0x=\frac{c}{\gcd(a,b)}x_0,y=\frac{c}{\gcd(a,b)}y_0x=gcd(a,b)cx0,y=gcd(a,b)cy0

因此,ax+by=cax+by=cax+by=c 的所有解可表示为:
x=cgcd⁡(a,b)x0+bgcd⁡(a,b)k,y=cgcd⁡(a,b)y0−agcd⁡(a,b)kx=\frac{c}{\gcd(a,b)}x_0+\frac{b}{\gcd(a,b)}k, y=\frac{c}{\gcd(a,b)}y_0-\frac{a}{\gcd(a,b)}kx=gcd(a,b)cx0+gcd(a,b)bk,y=gcd(a,b)cy0gcd(a,b)ak

其中 kkk 为整数。

gcd⁡(a,b)∤c\gcd(a,b) \nmid cgcd(a,b)c 时,无解。根据整除性质易证。

七、线性同余方程

形如 ax≡c(modb)ax\equiv c\pmod baxc(modb) 的方程被称为线性同余方程。

八、求解线性同余方程

线性同余方程 ax≡c(modb)ax\equiv c\pmod baxc(modb) 的解与 ax+by=cax+by=cax+by=c 的解等价。同时,这两个方程解的存在性也相同。即当 gcd⁡(a,b)∣c\gcd(a,b)\mid cgcd(a,b)c 时,方程存在无数解,当 gcd⁡(a,b)∤c\gcd(a,b)\nmid cgcd(a,b)c 时,方程无解。

因此采用扩展欧几里得算法求出二元一次不定方程的解,那么这组解也是线性同余方程的解(此时无需关注 yyy 的解是多少,只关注 xxx 的解即可)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值