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

一、最大公约数

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

二、欧几里得算法

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

接下来给出证明:
a , b a,b a,b 的公约数必然为 b , a   m o d   b b, a \bmod b b,amodb 的公约数。
d d d a , b a,b a,b 的公约数, a = k b + c a=kb+c a=kb+c,则 d ∣ a , d ∣ b d \mid a, d \mid b da,db,则 a   m o d   b = c a \bmod b = c amodb=c,由于 d ∣ a , d ∣ ( k b ) d \mid a, d \mid (kb) da,d(kb),故 d ∣ c d \mid c dc ,因此 d ∣ ( a   m o d   b ) d \mid (a \bmod b) d(amodb),又因为 d ∣ b d \mid b db,所以 a , b a,b a,b 的公约数必然为 b , a   m o d   b b, a\bmod b b,amodb 的公约数。
b , a   m o d   b b, a \bmod b b,amodb 的公约数必然为 a , b a,b a,b 的公约数。
d d d b , a   m o d   b b, a\bmod b b,amodb 的公约数, a = k b + c a=kb+c a=kb+c d ∣ b , d ∣ ( a   m o d   b ) d \mid b, d\mid (a\bmod b) db,d(amodb) ,则 a   m o d   b = c a \bmod b=c amodb=c,由于 d ∣ ( k b ) , d ∣ c d \mid (kb), d \mid c d(kb),dc,故 d ∣ a d \mid a da,又因为 d ∣ b d \mid b db,所以 b , a   m o d   b b, a\bmod b b,amodb 的公约数必然为 a , b a, b a,b 的公约数。

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

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

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

递归过程中 a   m o d   b a \bmod b amodb 至少将 a a a 的规模减半,所以递归层数为 log ⁡ n \log n logn 层,复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

三、多个数的最大公约数

计算多个整数的最大公约数时可以根据:
gcd ⁡ ( a 1 , a 2 , a 3 , . . . , a n ) = gcd ⁡ ( g c d ( a 1 , a 2 ) , a 3 , a 4 , . . . , a n ) \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)

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

四、扩展欧几里得算法

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

a x + b y = b x 0 + ( a − ⌊ a b ⌋ × b ) y 0 ax+by=bx_0+(a-\lfloor\frac{a}{b}\rfloor\times b)y_0 ax+by=bx0+(aba×b)y0

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

故可以得到原方程的解为 x = y 0 , y = x 0 − ⌊ a b ⌋ y 0 x=y_0,y=x_0-\lfloor\frac{a}{b}\rfloor y_0 x=y0,y=x0bay0。这样,在得知方程②解的情况下可以推得方程①的解。那么如何求出方程②的解呢?
通过观察两个方程的系数可以发现,从① → \rarr ②的过程中,系数会通过取模减小的,那么同欧几里得算法一样,不断递归,使系数减小,直到 b = 0 b=0 b=0 ,此时根据欧几里得算法有 a = gcd ⁡ ( a , b ) a=\gcd(a,b) a=gcd(a,b),求出此时方程 gcd ⁡ ( a , b ) x + 0 y = gcd ⁡ ( a , b ) \gcd(a,b)x + 0y=\gcd(a,b) gcd(a,b)x+0y=gcd(a,b) 的解为 x = 1 , y x=1,y x=1,y 为任意值,不妨设 y = 0 y=0 y=0,不断回溯得到原方程 a x + b y = 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 = x 0 , y = y 0 x=x_0, y=y_0 x=x0,y=y0 满足性质 ∣ x 0 ∣ < b , ∣ y 0 ∣ < a | x_0 | < b, | y_0 | < a x0<b,y0<a 。采用归纳法证明如下:
不妨假设共进行 n n n 层递归,原方程为 a x + b y = gcd ⁡ ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b),第 i i i 层递归得到的方程为 a i x + b i y = gcd ⁡ ( a , b ) a_ix+b_iy=\gcd(a,b) aix+biy=gcd(a,b),该层递归得到的解为 x = x i , y = y i x=x_i, y=y_i x=xi,y=yi ,递归出口 a n x + b n y = gcd ⁡ ( a , b ) a_nx+b_ny=\gcd(a,b) anx+bny=gcd(a,b),其中 b n = 0 b_n=0 bn=0
① 当 gcd ⁡ ( a , b ) = b i \gcd(a,b)=b_i gcd(a,b)=bi 时:
a   m o d   b = 0 a \bmod b = 0 amodb=0,因此递归层数 i = n − 1 i=n-1 i=n1 ,得到解为 x = x n − 1 = 1 , y = y n − 1 = 0 x=x_{n-1}=1, y=y_{n-1}=0 x=xn1=1,y=yn1=0,此时满足 ∣ x n − 1 ∣ < ∣ b n − 1 ∣ , ∣ y n − 1 ∣ < ∣ a n − 1 ∣ | x_{n-1} | < |b_{n-1}|, |y_{n-1}| < |a_{n-1}| xn1<bn1,yn1<an1
② 当 gcd ⁡ ( a , b ) ≠ b i \gcd(a,b) \neq b_i gcd(a,b)=bi 时:
不妨假设第 i + 1 i+1 i+1 层递归得到的解 x = x i + 1 , y = y i + 1 x=x_{i+1}, y=y_{i+1} x=xi+1,y=yi+1 满足 ∣ x i + 1 ∣ < ∣ b i + 1 ∣ , ∣ y i + 1 ∣ < ∣ a i + 1 ∣ | x_{i+1} | < | b_{i+1} |, | y_{i+1} | < | a_{i+1} | xi+1<bi+1,yi+1<ai+1 。根据系数递归的公式有 a i + 1 = b i , b i + 1 = a i   m o d   b i a_{i+1} = b_i, b_{i+1} = a_i\bmod b_i ai+1=bi,bi+1=aimodbi
则对于 x i x_i xi
∣ x i ∣ = ∣ y i + 1 ∣ < ∣ a i + 1 ∣ = ∣ b i ∣ | x_i | = | y_{i+1} | < | a_{i+1} | = | b_i | xi=yi+1<ai+1=bi

对于 y i y_i yi
∣ y i ∣ = ∣ x i + 1 − ⌊ a i b i ⌋ y i + 1 ∣ ⩽ ∣ x i + 1 ∣ + ∣ ⌊ a i b i ⌋ y i + 1 ∣ = ∣ x i + 1 ∣ + ⌊ a i b i ⌋ ∣ y i + 1 ∣ ⩽ ∣ b i + 1 ∣ − ⌊ a i b i ⌋ ∣ y i + 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

⩽ a i   m o d   b i + ⌊ a i b i ⌋ ∣ y i + 1 ∣ ⩽ a i − ⌊ a i b i ⌋ b i + ⌊ a i b i ⌋ ∣ y i + 1 ∣ ⩽ a i − ⌊ a i b i ⌋ ( b i − ∣ y i + 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)

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

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

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

因此, a x + b y = c ax+by=c ax+by=c 的所有解可表示为:
x = c gcd ⁡ ( a , b ) x 0 + b gcd ⁡ ( a , b ) k , y = c gcd ⁡ ( a , b ) y 0 − a gcd ⁡ ( a , b ) k x=\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)}k x=gcd(a,b)cx0+gcd(a,b)bk,y=gcd(a,b)cy0gcd(a,b)ak

其中 k k k 为整数。

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

七、线性同余方程

形如 a x ≡ c ( m o d b ) ax\equiv c\pmod b axc(modb) 的方程被称为线性同余方程。

八、求解线性同余方程

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值