欧几里得算法

首先感谢 C20210413 大佬, C20211711LJS 社花大佬,14大佬对于正确使用 m a r k d o w n markdown markdown 语法给予的帮助

人物介绍

欧几里得:(英文: E u c l i d Euclid Euclid;希腊文:Ευκλειδης ,约公元前330年—公元前275年),古希腊人,数学家,被称为“几何之父”。他最著名的著作《几何原本》是欧洲数学的基础,提出五大公设,欧几里得几何,被广泛的认为是历史上最成功的教科书。欧几里得也写了一些关于透视、圆锥曲线、球面几何学及数论的作品。

算法本身

欧几里得算法,即辗转相除法,用于求 a , b a, b a,b 两数的最大公约数数------ gcd ⁡ ( a , b ) \gcd(a, b) 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)

证明:我们设 r = a   m o d   b r = a \bmod b r=amodb,显然 r r r 也可以表示为 r = a − k × b r = a - k \times b r=ak×b,其中 k = a / b k = a / b k=a/b

假设 d d d a , b a, b a,b 的一个公约数,则有: a   m o d   d = 0 a \bmod d = 0 amodd=0 b   m o d   d = 0 b \bmod d = 0 bmodd=0

a = x × d , b = y × d a = x \times d, b = y \times d a=x×d,b=y×d,且 x , y x, y x,y 为整数。而 r = a − k × b r = a - k \times b r=ak×b

所以 r = x × d − y × d × k = ( x − k × y ) × d r = x \times d - y \times d \times k = (x - k \times y) \times d r=x×dy×d×k=(xk×y)×d,显然, x − k × y x - k \times y xk×y 为整数。

所以 r r r d d d 的倍数。所以 r   m o d   d = 0 r \bmod d = 0 rmodd=0,又因为 b   m o d   d = 0 b \bmod d = 0 bmodd=0,且 r = a   m o d   b r = a \bmod b r=amodb

所以有: d = gcd ⁡ ( b , a   m o d   b ) d = \gcd(b, a \bmod b) d=gcd(b,amodb)

根据以上原理,经过一步代换后,一定会出现 a > b a > b a>b。以后的每次代换一定会将 a , b a, b a,b 不断的缩小,而当 b = 0 b = 0 b=0 时,它们的最大公约数为 a a a


代码实现

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

已被严格证明时间复杂度为: O ( log ⁡   m a x ( a , b ) ) O(\log\ max(a, b)) O(log max(a,b))

扩展欧几里得算法

简称扩欧。
可以在已知整数 a , b a, b a,b 的情况下求不定方程 a × x + b × y = gcd ⁡ ( a , b ) a \times x + b \times y = \gcd(a, b) a×x+b×y=gcd(a,b) 的一组整数解。

首先,我们来证明一个结论:对于整数 a , b a, b a,b,必定存在整数 x , y x, y x,y 满足 a × x + b × y = gcd ⁡ ( a , b ) a \times x + b \times y = \gcd(a, b) a×x+b×y=gcd(a,b)

证明:设 a × x 1 + b × y 1 = gcd ⁡ ( a , b ) a \times x1 + b \times y1 = \gcd(a, b) a×x1+b×y1=gcd(a,b),且 b × x 2 + ( a   m o d   b ) × y 2 = gcd ⁡ ( b , a   m o d   b ) b \times x2 + (a \bmod b) \times y2 = \gcd(b, a \bmod b) b×x2+(amodb)×y2=gcd(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)

所以 a × x 1 + b × y 1 = b × x 2 + ( a   m o d   b ) × y 2 a \times x1 + b \times y1 = b \times x2 + (a \bmod b) \times y2 a×x1+b×y1=b×x2+(amodb)×y2

因为 a   m o d   b = a − b × k a \bmod b = a - b \times k amodb=ab×k,所以 a × x 1 + b × y 1 = b × x 2 + ( a − b × k ) × y 2 a \times x1 + b \times y1 = b \times x2 + (a - b \times k) \times y2 a×x1+b×y1=b×x2+(ab×k)×y2

又因为 k = a / b k = a / b k=a/b,所以 a × x 1 + b × y 1 = b × x 2 + ( a − b × ( a / b ) ) × y 2 a \times x1 + b \times y1 = b \times x2 + (a - b \times (a / b)) \times y2 a×x1+b×y1=b×x2+(ab×(a/b))×y2

整理得, a × x 1 + b × y 1 = a × y 2 + b × ( x 2 − ( a / b ) × y 2 ) a \times x1 + b \times y1 = a \times y2 + b \times (x2 - (a / b) \times y2) a×x1+b×y1=a×y2+b×(x2(a/b)×y2)

显然, x 1 = y 2 , y 1 = ( x 2 − ( a / b ) × y 2 ) x1 = y2, y1 = (x2 - (a / b) \times y2) x1=y2,y1=(x2(a/b)×y2),其中 x 2 , y 2 x2, y2 x2,y2 是关于 gcd ⁡ ( b , a   m o d   b ) \gcd(b, a\bmod b) gcd(b,amodb) 的不定方程的解。这就和欧几里得算法联系起来了,因为 x 1 , x 2 x1, x2 x1,x2 是由 x 2 , y 2 x2, y2 x2,y2 得来的,且 x 2 , y 2 x2, y2 x2,y2 关于 gcd ⁡ ( b , a   m o d   b ) \gcd(b, a \bmod b) gcd(b,amodb) 不断变小。

最后,当 x , y x, y x,y 是关于 gcd ⁡ ( a , 0 ) \gcd(a, 0) gcd(a,0) 的不定方程的解时,不难发现 a × x + b × y = a a \times x + b \times y = a a×x+b×y=a, 所以此时 x = 1 , y = 0 x = 1, y = 0 x=1,y=0。这就是递归求解的边界。故因为边界确定,所以对于整数 a , b a, b a,b,必定存在整数 x , y x, y x,y 满足 a × x + b × y = gcd ⁡ ( a , b ) a \times x + b \times y = \gcd(a, b) a×x+b×y=gcd(a,b)

不难通过刚刚的证明过程,写出代码:

long long x, y;
void Ex_Gcd(long long a, long long b) {
	if(b == 0) {
		x = 1;
		y = 0; 
		return ;
	} 
	Ex_Gcd(b, a % b);
	long long t = x;
	x = y;
	y = t - a / b * y; 
}

应用


Part 1 判断不定方程 a × x + b × y = c a \times x + b \times y = c a×x+b×y=c 是否有解

根据扩欧:假设 d = gcd ⁡ ( a , b ) d = \gcd(a, b) d=gcd(a,b) ,则 a × x + b × y = d a \times x + b \times y = d a×x+b×y=d 一定有解。

所以 ( a × x + b × y ) × k = d × k (a \times x + b \times y) \times k = d \times k (a×x+b×y)×k=d×k 一定有解 ( k k k 为整数)。

显然 a × x + b × y = d × k a \times x + b \times y = d \times k a×x+b×y=d×k 一定有解。

所以不定方程 a × x + b × y = c a \times x + b \times y = c a×x+b×y=c 中当 c   m o d   gcd ⁡ ( a , b ) = 0 c \bmod \gcd(a, b) = 0 cmodgcd(a,b)=0 时,方程有解。否则无解。


Part 2 不定方程 a × x + b × y = c a \times x + b \times y = c a×x+b×y=c 的通解

对于不定方程 a × x + b × y = c a \times x + b \times y = c a×x+b×y=c,我们设 d = gcd ⁡ ( a , b ) d = \gcd(a, b) d=gcd(a,b)。当 c   m o d   d = 0 c \bmod d = 0 cmodd=0 时有解。

利用扩欧求出 a × x ′ + b × y ′ = gcd ⁡ ( a , b ) = d a \times x' + b \times y' = \gcd(a, b) = d a×x+b×y=gcd(a,b)=d 的一组解 x ′ , y ′ x', y' x,y

a × x + b × y = c a \times x + b \times y = c a×x+b×y=c 一定有一组解为 x = x ′ × c / d , y = y ′ × c / d x = x' \times c / d, y = y' \times c / d x=x×c/d,y=y×c/d

又因为原方程可化为 a × x + k × a × b + b × y − k × a × b = c a \times x + k \times a \times b + b \times y - k \times a \times b = c a×x+k×a×b+b×yk×a×b=c。其中 k k k 为整数。

a × ( x + b × k ) + b × ( y − a × k ) = c a \times (x + b \times k) + b \times (y - a \times k) = c a×(x+b×k)+b×(ya×k)=c

所以 :
x = x ′ × c / d + b × k / d x = x' \times c / d + b \times k / d x=x×c/d+b×k/d

y = y ′ × c / d − a × k / d y = y' \times c / d - a \times k / d y=y×c/da×k/d


Part 3 模线性方程 a × x ≡ b a \times x \equiv b a×xb ( m o d (mod (mod n ) n) n) 的解

首先,如果 a ≡ b a \equiv b ab ( m o d (mod (mod n ) n) n),则 ( a − b )   m o d   n = 0 (a - b) \bmod n = 0 (ab)modn=0

所以,如果 a × x ≡ b a \times x \equiv b a×xb ( m o d (mod (mod n ) n) n),则 ( a × x − b )   m o d   n = 0 (a \times x - b) \bmod n = 0 (a×xb)modn=0

于是,我们设 a × x − b = n × y a \times x - b = n \times y a×xb=n×y,其中 y y y 为整数。

那么模线性方程 a × x ≡ b a \times x \equiv b a×xb ( m o d (mod (mod n ) n) n)可化为不定方程 a × x − n × y = b a \times x - n \times y = b a×xn×y=b

解法详见 P a r t 2 Part 2 Part2


Part 4 乘法逆元

首先, a × x ≡ 1 a \times x \equiv1 a×x1 ( m o d (mod (mod n ) n) n)的解称为 a a a 关于模 n n n 的乘法逆元。

什么情况下 a a a 的逆元存在?由 P a r t 3 Part 3 Part3 可得当 a x − n y = 1 ax - ny = 1 axny=1 有解时,存在 a a a 的逆元。

所以由 P a r t 1 Part 1 Part1 1 1 1 gcd ⁡ ( a , n ) \gcd(a, n) gcd(a,n) 的倍数。所以 gcd ⁡ ( a , n ) = 1 \gcd(a, n) = 1 gcd(a,n)=1,即 a a a n n n 互质。

故,在 gcd ⁡ ( a , n ) = 1 \gcd(a, n) = 1 gcd(a,n)=1 的前提下, a × x ≡ 1 a \times x \equiv1 a×x1 ( m o d (mod (mod n ) n) n)的解就是 a a a 关于模 n n n 的乘法逆元。

(其中, x < n x < n x<n 或者说 x = x   m o d   n x = x \bmod n x=xmodn


补充

1.费马小定理

费马: 皮埃尔·德·费马,法国律师和业余数学家。他在数学上的成就不比职业数学家差,他似乎对数论最有兴趣,亦对现代微积分的建立有所贡献。被誉为“业余数学家之王”。

定理本身: 如果 p p p 为质数,且 a a a p p p 互质,即 gcd ⁡ ( a , p ) = 1 \gcd(a, p) = 1 gcd(a,p)=1,那么一定有 a p − 1 ≡ 1 a^{p - 1} \equiv 1 ap11 ( m o d (mod (mod p ) p) p)

求乘法逆元: 因为 a p − 1 ≡ 1 a^{p - 1} \equiv 1 ap11 ( m o d (mod (mod p ) p) p),所以 a × a p − 2 ≡ 1 a \times a^{p - 2} \equiv 1 a×ap21 ( m o d (mod (mod p ) p) p)。故 a p − 2 a^{p - 2} ap2 就是 a a a 关于模 p p p 的乘法逆元

2.关于同余的一些证明
  • 1) 如果 a ≡ b a \equiv b ab ( m o d (mod (mod m ) m) m) x ≡ y x \equiv y xy ( m o d (mod (mod m ) m) m),则 a + x ≡ b + y a + x \equiv b + y a+xb+y ( m o d (mod (mod m ) m) m)

证明:首先,我们一定能找到 k a k_a ka k b k_b kb 使得 a − k a × m = b − k b × m a - k_a \times m = b - k_b \times m aka×m=bkb×m,也存在 k x k_x kx k y k_y ky 使得 x − k x × m = y − k y × m x - k_x \times m = y - k_y \times m xkx×m=yky×m

所以 a − k a × m + x − k x × m = b − k b × m + y − k y × m a - k_a \times m + x - k_x \times m = b - k_b \times m + y - k_y \times m aka×m+xkx×m=bkb×m+yky×m,即 a + x − m × ( k a + k x ) = b + y − m × ( k b + k y ) a + x - m \times (k_a + k_x) = b + y - m \times (k_b + k_y) a+xm×(ka+kx)=b+ym×(kb+ky)

a + x ≡ b + y a + x \equiv b + y a+xb+y ( m o d (mod (mod m ) m) m)


  • 2) 如果 a ≡ b a \equiv b ab ( m o d (mod (mod m ) m) m) x ≡ y x \equiv y xy ( m o d (mod (mod m ) m) m),则 a × x ≡ b × y a \times x \equiv b \times y a×xb×y ( m o d (mod (mod m ) m) m)

证明:首先,我们一定能找到 k a k_a ka k b k_b kb 使得 a − k a × m = b − k b × m a - k_a \times m = b - k_b \times m aka×m=bkb×m,也存在 k x k_x kx k y k_y ky 使得 x − k x × m = y − k y × m x - k_x \times m = y - k_y \times m xkx×m=yky×m(同上)。

所以 ( a − k a × m ) × ( x − k x × m ) = ( b − k b × m ) × ( y − k y × m ) (a - k_a \times m) \times (x - k_x \times m) = (b - k_b \times m) \times (y - k_y \times m) (aka×m)×(xkx×m)=(bkb×m)×(yky×m),展开后必然得到 a × x − m × ( . . . ) = b × y − m × ( . . . ) a \times x - m \times (...) = b \times y - m \times (...) a×xm×(...)=b×ym×(...)

a × x ≡ b × y a \times x \equiv b \times y a×xb×y ( m o d (mod (mod m ) m) m)


  • 3) 如果 a × c ≡ b × c a \times c \equiv b \times c a×cb×c ( m o d (mod (mod m ) m) m) gcd ⁡ ( c , m ) = 1 \gcd(c, m) = 1 gcd(c,m)=1,则 a ≡ b a \equiv b ab ( m o d (mod (mod m ) m) m)

证明:首先,我们一定能找到 k a c k_{ac} kac k b c k_{bc} kbc 使得 a × c − k a c × m = b × c − k b c × m a \times c - k_{ac} \times m = b \times c - k_{bc} \times m a×ckac×m=b×ckbc×m。移项可得 a × c − b × c = k a c × m − k b c × m a \times c - b \times c = k_{ac} \times m - k_{bc} \times m a×cb×c=kac×mkbc×m,即 ( a − b ) × c = m × ( k a c − k b c ) (a - b) \times c = m \times (k_{ac} - k_{bc}) (ab)×c=m×(kackbc)

又因为 gcd ⁡ ( c , m ) = 1 \gcd(c, m) = 1 gcd(c,m)=1 所以 ( a − b ) (a - b) (ab) 一定被 m m m 整除。

a ≡ b a \equiv b ab ( m o d (mod (mod m ) m) m)


完结撒花~

你可能感兴趣的:(数学,算法,c++)