最大公约数
最大公约数 ( G r e a t e s t C o m m o n D i v i s o r ) (Greatest Common Divisor) (GreatestCommonDivisor),常缩写为 G C D GCD GCD。一组数的公约数,是指同时同时整除这组数中每一个数的数。最大公约数,是指所有公约数中最大的数。
那么如何求最大公约数呢?我们先考虑两个数的情况。
欧几里得算法
现在我们一张两个数,那么要如何求它们的最大公约数呢?我们不妨设 a > b a>b a>b。
-
当 b ∣ a b\mid a b∣a时,那么 b b b就是两者的最大公约数
-
当 b ∤ a b \nmid a b∤a,即 a = b × q + r a=b\times q+r a=b×q+r,其中 r < b r<b r<b时,我们可以证明得到 g c d ( a , b ) = g c d ( b , a m o d b ) gcd(a,b) = gcd(b,a \: mod\: b) gcd(a,b)=gcd(b,amodb)。
设 a = b × k + c a=b\times k+c a=b×k+c,显然有 c = a m o d b c=a\:mod\:b c=amodb。设, d ∣ a , d ∣ b d\:|\:a,d\:|\:b d∣a,d∣b,则有 c ∣ d c\:|\:d c∣d,因为 c = a − b × k , c=a-b\times k, c=a−b×k, 所以 d ∣ ( a − b × k ) d\:|(a-b\times k) d∣(a−b×k),即 d ∣ ( a m o d b ) d\:|(a\:mod\:b) d∣(amodb)。
既然 d d d是它们两个的公约数,所以有 g c d ( a , b ) = g c d ( b , a m o d b ) gcd(a,b) = gcd(b,a \: mod\: b) gcd(a,b)=gcd(b,amodb)。于是我们也就得到了关于两个数的最大公约数的一个递归求法。时间复杂度为 O ( l o g N ) O(logN) O(logN)。
inline int gcd(int a, int b){ return b ? gcd(b,a%b) : a; }
这个函数也揭示了一个概念,即任何非零整数和零的最大公约数为它本身。
当 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1时,我们称之为互质。
最小公倍数
最小公倍数(Least Common Multiple),常缩写为 L C M LCM LCM。两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。
我们都知道 g c d ( a , b ) × l c m ( a , b ) = a × b gcd(a,b)\times lcm(a,b)=a\times b gcd(a,b)×lcm(a,b)=a×b。所以我们要求两个数的最小公倍数,先求出最大公约数即可。