最 大 公 约 数 [Greatest Common Divisor]

最大公约数 最大公约数 最大公约数

欧几里得算法 欧几里得算法 欧几里得算法

不妨设 a > b 不妨设a>b 不妨设a>b
1. 1. 1. 能整除 能整除 能整除
b 是 a 的约数,那么 b 就是二者的最大公约数 b是a的约数,那么b就是二者的最大公约数 ba的约数,那么b就是二者的最大公约数

2. 2. 2. 不能整除 不能整除 不能整除
① ① g c d ( a , b ) = > g c d ( b , a gcd(a,b)=>gcd(b, a gcd(a,b)=>gcd(b,a m o d mod mod b ) b) b)

设 a = b k + c ( c < b ) ,显然有 c = a 设a=bk+c(c<b),显然有c=a a=bk+c(c<b),显然有c=a m o d mod mod b 。设 d b。设d b。设d ∣ | a , d a,d ad ∣ | b ,则 c = a − b k , c d = a d − b d k , c d 为整数,即 d b,则c=a-bk,\frac{c}{d}=\frac{a}{d}-\frac{b}{d}k,\frac{c}{d}为整数,即d b,则c=abk,dc=dadbkdc为整数,即d ∣ | c , ∴ g c d ( a , b ) = > g c d ( b , a c,∴gcd(a,b)=>gcd(b, a cgcd(a,b)=>gcd(b,a m o d mod mod b ) b) b)

② ② g c d ( b , a gcd(b, a gcd(b,a m o d mod mod b ) = > g c d ( a , b ) b)=>gcd(a,b) b)=>gcd(a,b)

设 d 设d d ∣ | b , d b,d bd ∣ | ( a (a (a m o d mod mod b ) b) b)
= > a m o d b d = a d − b d k = > a d = b d k + a m o d b d , a d 为整数,即 d =>\frac{amodb}{d}=\frac{a}{d}-\frac{b}{d}k=>\frac{a}{d}=\frac{b}{d}k+\frac{amodb}{d},\frac{a}{d}为整数,即d =>damodb=dadbk=>da=dbk+damodbda为整数,即d ∣ | a , ∴ g c d ( b , a a,∴gcd(b, a agcd(b,a m o d mod mod b ) = > g c d ( a , b ) b)=>gcd(a,b) b)=>gcd(a,b)

综上, g c d ( a , b ) = g c d ( b , a 综上,gcd(a,b)=gcd(b, a 综上,gcd(a,b)=gcd(b,a m o d mod mod b ) b) b)

实现
①递归求法 ①递归求法 递归求法

//version 1
int gcd(int a, int b){
	if(!b) return a;//!b<=>b == 0
	return gcd(b, a % b);
}
//version 2
int gcd(int a, int b){return (!b) ? a : gcd(b, a % b);}//!b<=>b == 0

②迭代求法 ②迭代求法 迭代求法

//version 1
int gcd(int a, int b){
	while(b){//b<=>b != 0
		int tmp = a;
		a = b;
		b = tmp % b;
	}
	return a;
}

异或使人疑惑

//version 2
int gcd(int a, int b){
	while(b){//b<=>b != 0
		a %= b;
		b ^= a;
		a ^= b;
		b ^= a;
	}
	return a;
}
//version 3
int gcd(int a, int b){
    while(b ^= a ^= b ^= a %= b);
    return a;
}

c + + 14 c++14 c++14

__gcd(a, b);

c + + 17 c++17 c++17

std::gcd(a, b);

时间复杂度为 O ( l o g 时间复杂度为O(log 时间复杂度为O(log m a x ( a , b ) ) max(a,b)) max(a,b))

  • a ≥ b , g c d ( a , b ) = g c d ( b , a a≥b,gcd(a,b)=gcd(b,a abgcd(a,b)=gcd(b,a m o d mod mod b ) , a b),a b)a m o d mod mod b 会让 a 至少减半 b会让a至少减半 b会让a至少减半
    证明: 证明: 证明:
    ①当 b ≤ a 2 时, a ①当b≤\frac{a}{2}时,a b2a时,a m o d mod mod b 的最大值为 b − 1 < a 2 b的最大值为b-1<\frac{a}{2} b的最大值为b1<2a
    ②当 b > a 2 时,有 a ②当b>\frac{a}{2}时,有a b>2a时,有a m o d mod mod b = a − ⌊ a b ⌋ × b b=a-\lfloor \frac{a}{b} \rfloor×b b=aba×b
    ∵ b > a 2 ∵b>\frac{a}{2} b>2a
    ∴ a b < 2 ∴\frac{a}{b}<2 ba<2
    ∴ ⌊ a b ⌋ = 1 ∴\lfloor \frac{a}{b} \rfloor=1 ba=1
    ∴ a ∴a a m o d mod mod b = a − b b=a-b b=ab
    ∵ b > a 2 ∵b>\frac{a}{2} b>2a
    ∴ a − b < a 2 ∴a-b<\frac{a}{2} ab<2a
    即 a 即a a m o d mod mod b < a 2 b<\frac{a}{2} b<2a
    综上, a 综上,a 综上,a m o d mod mod b < a 2 b<\frac{a}{2} b<2a
    证毕 . 证毕. 证毕.
    时间复杂度为 O ( l o g 时间复杂度为O(log 时间复杂度为O(log a ) = O ( n ) a)=O(n) a)=O(n)

  • a < b , g c d ( a , b ) = g c d ( b , a ) = g c d ( a , b a<b,gcd(a,b)=gcd(b,a)=gcd(a,b a<bgcd(a,b)=gcd(b,a)=gcd(a,b m o d mod mod a ) a) a)
    时间复杂度为 O ( l o g 时间复杂度为O(log 时间复杂度为O(log b ) = O ( n ) b)=O(n) b)=O(n)

欧几里得算法求斐波那契数列相邻两项的最大公约数,会让该算法达到最坏复杂度 欧几里得算法求斐波那契数列相邻两项的最大公约数,会让该算法达到最坏复杂度 欧几里得算法求斐波那契数列相邻两项的最大公约数,会让该算法达到最坏复杂度

F n = F n − 1 + F n − 2 F_n=F_{n-1}+F_{n-2} Fn=Fn1+Fn2
F n F_n Fn m o d mod mod F n − 1 = ( F n − 1 + F n − 2 ) F_{n-1}=(F_{n-1}+F_{n-2}) Fn1=(Fn1+Fn2) m o d mod mod F n − 1 F_{n-1} Fn1
∵ F n − 1 ∵F_{n-1} Fn1 m o d mod mod F n − 1 = 0 F_{n-1}=0 Fn1=0
∴ F n ∴F_n Fn m o d mod mod F n − 1 = F n − 2 F_{n-1}=F_{n-2} Fn1=Fn2 m o d mod mod F n − 1 = F n − 2 F_{n-1}=F_{n-2} Fn1=Fn2

g c d ( F n , F n − 1 ) = g c d ( F n − 1 , F n − 2 ) = … = g c d ( F 2 , F 1 ) gcd(F_n,F_{n-1})=gcd(F_{n-1},F_{n-2})=…=gcd(F_2,F_1) gcd(Fn,Fn1)=gcd(Fn1,Fn2)==gcd(F2,F1)

迭代次数为 n 次,时间复杂度为 O ( n ) 迭代次数为n次,时间复杂度为O(n) 迭代次数为n次,时间复杂度为O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值