【数论】最大公因数和最小公倍数(GCD和LCM)

最大公因数(GCD)

两个数的最大公因数很好做,使用内置的库函数即可,注意x和y的类型要相同。

ll gcd = __gcd (x, y);

如果要求多个数的最大公因数,那么初始化为0(因为根据定义,0和任何数x的gcd都是x,所以0是gcd操作的幺元),然后分别进行gcd即可。

ll gcd = 0;
for (int i = 1; i <= n; ++i) {
    gcd = __gcd (gcd, a[i]);
}

负数也可以用gcd,不过不推荐这样操作,让自己变得混淆。尽量对操作数都进行一次abs操作就好了。

每个数都有固定的质因数分解形式,也就是算术基本定理

GCD的过程就是对每个数的对应质数的幂取最小值。

最小公倍数(LCM)

两个数的LCM可以用下列的方法直接算出来:

ll lcm = x / __gcd (x, y) * y;

其中先除后乘是尽可能避免溢出,尽量保持这个习惯。

多个数的lcm就稍微少见一些。

ll lcm = 1;
for (int i = 1; i <= n; ++i) {
    ll gcd = __gcd (lcm, a[i]);
    lcm = lcm / gcd * a[i];
}

每个数都有固定的质因数分解形式,也就是算术基本定理

LCM的过程就是对每个数的对应质数的幂取最大值。

由算术基本定理,可以这样证明:
假设目前求出了所有元素的各个幂次的最大值,初始化自然为0,所以他们的乘积为1。1是lcm操作的幺元。

根据上面的算法,求出当前lcm和a[i]的gcd。在算术基本定理下,对于每个幂次都是保留了其中的最小值。

然后lcm和a[i]做乘法,再除以gcd,在算术基本定理下,相当于:

每种质数的幂先做加法,然后减去他们之间的最小值,所以相当于保留最大值。

于是得证。

几个可能有用的上界:

前i个数的gcd。

i = 1, lcm = 1
i = 2, lcm = 2
i = 3, lcm = 6
i = 4, lcm = 12
i = 5, lcm = 60
i = 6, lcm = 60
i = 7, lcm = 420
i = 8, lcm = 840
i = 9, lcm = 2520
i = 10, lcm = 2520
i = 11, lcm = 27720
i = 12, lcm = 27720
i = 13, lcm = 360360 (4e5)
i = 14, lcm = 360360
i = 15, lcm = 360360
i = 16, lcm = 720720 (7e5)
i = 17, lcm = 12252240 (1e7)
i = 18, lcm = 12252240
i = 19, lcm = 232792560 (2e8)
i = 20, lcm = 232792560
i = 21, lcm = 232792560
i = 22, lcm = 232792560
i = 23, lcm = 5354228880 (5e9 > 2e9 = INT_MAX)
i = 24, lcm = 5354228880
i = 25, lcm = 26771144400
i = 26, lcm = 26771144400
i = 27, lcm = 80313433200
i = 28, lcm = 80313433200
i = 29, lcm = 2329089562800
i = 30, lcm = 2329089562800
i = 31, lcm = 72201776446800
i = 32, lcm = 144403552893600
i = 33, lcm = 144403552893600
i = 34, lcm = 144403552893600
i = 35, lcm = 144403552893600
i = 36, lcm = 144403552893600
i = 37, lcm = 5342931457063200
i = 38, lcm = 5342931457063200
i = 39, lcm = 5342931457063200
i = 40, lcm = 5342931457063200
i = 41, lcm = 219060189739591200
i = 42, lcm = 219060189739591200 (2e18)
i = 43, lcm = -9027155914907130016 (? > 9e18 = LONG_LONG_MAX)
i = 1, p = 2, prod = 2
i = 2, p = 3, prod = 6
i = 3, p = 5, prod = 30
i = 4, p = 7, prod = 210
i = 5, p = 11, prod = 2310
i = 6, p = 13, prod = 30030
i = 7, p = 17, prod = 510510 (5e5)
i = 8, p = 19, prod = 9699690 (1e7)
i = 9, p = 23, prod = 223092870 (2e8)
i = 10, p = 29, prod = 6469693230 (6e9 > 2e9 = INT_MAX)
i = 11, p = 31, prod = 200560490130
i = 12, p = 37, prod = 7420738134810
i = 13, p = 41, prod = 304250263527210
i = 14, p = 43, prod = 13082761331670030
i = 15, p = 47, prod = 614889782588491410 (6e17)
i = 16, p = 53, prod = -4304329670229058502 (? > 9e18 = LONG_LONG_MAX)
posted @ 2024-04-14 13:05  purinliang  阅读(52)  评论(0编辑  收藏  举报