最大公约数 最大公约数 最大公约数
欧几里得算法 欧几里得算法 欧几里得算法
不妨设
a
>
b
不妨设a>b
不妨设a>b
1.
1.
1.
能整除
能整除
能整除
b
是
a
的约数,那么
b
就是二者的最大公约数
b是a的约数,那么b就是二者的最大公约数
b是a的约数,那么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 a,d ∣ | ∣ 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=a−bk,dc=da−dbk,dc为整数,即d ∣ | ∣ c , ∴ g c d ( a , b ) = > g c d ( b , a c,∴gcd(a,b)=>gcd(b, a c,∴gcd(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
b,d
∣
|
∣
(
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=da−dbk=>da=dbk+damodb,da为整数,即d
∣
|
∣
a
,
∴
g
c
d
(
b
,
a
a,∴gcd(b, a
a,∴gcd(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 a≥b,gcd(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 ①当b≤2a时,a m o d mod mod b 的最大值为 b − 1 < a 2 b的最大值为b-1<\frac{a}{2} b的最大值为b−1<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=a−⌊ba⌋×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=a−b
∵ b > a 2 ∵b>\frac{a}{2} ∵b>2a
∴ a − b < a 2 ∴a-b<\frac{a}{2} ∴a−b<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<b,gcd(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=Fn−1+Fn−2
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})
Fn−1=(Fn−1+Fn−2)
m
o
d
mod
mod
F
n
−
1
F_{n-1}
Fn−1
∵
F
n
−
1
∵F_{n-1}
∵Fn−1
m
o
d
mod
mod
F
n
−
1
=
0
F_{n-1}=0
Fn−1=0
∴
F
n
∴F_n
∴Fn
m
o
d
mod
mod
F
n
−
1
=
F
n
−
2
F_{n-1}=F_{n-2}
Fn−1=Fn−2
m
o
d
mod
mod
F
n
−
1
=
F
n
−
2
F_{n-1}=F_{n-2}
Fn−1=Fn−2
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,Fn−1)=gcd(Fn−1,Fn−2)=…=gcd(F2,F1)
迭代次数为 n 次,时间复杂度为 O ( n ) 迭代次数为n次,时间复杂度为O(n) 迭代次数为n次,时间复杂度为O(n)