前言: 在本文章中要介绍一下gcd和lcm的性质 ,以及一些使用的技巧 , 其中也包括一些定理的证明。
gcd 部分
gcd 是什么 ?
gcd 的全称是最大公约数(Greatest common divisor)
gcd 是对两个及以上的数的运算数才存在 , 但是一般的我们是求两个数的最大公约数即 gcd(a , b)
举个例子 , 4 , 12 的gcd 是多少呢 ? 答案是 4
4 的因数 1 2 2 4
12 的因数 1 2 3 4 6 12
其中我们发现 4 是他们最大的公共的因数
是不是非常的清楚明了!
gcd(a , b) 的形式化表达
对于任意的一个自然数 a , b 由唯一分解定理都可以表示成这样的形式
a=p1k1 ⋅ p2k2 ⋅ p3k3 ⋅ p4k4....... pnknb=p1l1 ⋅ p2l2 ⋅ p3l3 ⋅ p4l4....... pnln
那么我们的gcd(a , b) 可以形式化表示成这样
gcd (a , b)=p1min(k1,l1) ⋅ p2min(k2,l2) ⋅ p3min(k3,l3)......pnmin(kn,ln)
那我们该怎么求gcd(a , b) , 当然使用 辗转相除法!也叫欧几里得算法
欧几里得算法
欧几里得算法计算公式:
gcd(a , b)=gcd(b ,amod b),其中 mod 是取模
对应的代码也非常的好写
int gcd(int a , int b){
return b ? gcd(b , a % b) : a;
}
注: 本人目前还不清楚gcd(a , b) 证明,以后应该会知道的。
接下来介绍一下gcd 的一些性质
将 gcd(a,b) 记成 (a,b)
1 . (a,b)=(a,a+b)=(a+b,b)=(a−b,b)=(b,a−b)
2 . 结合律 : (a ,b , c)=((a,b),c)=(a,(b,c))
(a1,a2,a3.....,an)=(a1,(a2,......,an))=((a1,a2,......an−1)an)
对于这里的推论 , 其实我们可以发现 gcd(a1,a2,a3,......,an) 可以通过先对其中两个数的求公约数, 然后对剩下的ai进行一一的即可
3 . 互质 : (a,b)=(dk1,dk2) , 其中d为最大公约数, (k1,k2)=1 , 即 k1,k2 互质. 同时 k1,k2,k1+k2 三者互质
4 . 分配律 : (m a,m b)=m (a , b)
- 推论:
设(a,b,c)=1, 其中a,b,c 都是正整数 , 那么 (a,b)∗(b,c)=(ab,c).
(a , b)∗(b , c)=(ab , c)
证明:
(a , b) ∗ (b , c)
= (a(b,c),c(b,c)) // 分配律
= (ab,ac,bc,cc)
= (ab ,c (a,b,c)) // 结合律
= (ab , c) // 由题(a , b , c) = 1
证毕!
5 . 不知道名字的性质 :
gcd(a1,a2,a3,a4,.....,an)=gcd(a1,a1+a2,...,a1+a2+a3.....+an)
证明 gcd(a1,a2,a3,a4,.....,an)=gcd(a1,a1+a2,...,a1+a2+a3.....+an)
首先假设有 a , b 两数 , 很显然我们可以求出 gcd(a,b)=d
这里我们不妨设 a=dk1,b=dk2 , 同时将 gcd(a , b)记成 (a , b)
首先我们先来证明
(a,a+b)=(a,b)
这里我们可以将 (a , a + b) 写成 (dk1,d(k1+k2))
此时我们表示成 d(k1,(k1+k2))
因为(k1,(k1+k2))=1 , 所以 d(k1,(k1+k2))=1.
现在通过这个证明观察 , 我们发现其实对于n 元的也可以利用这种拆分方法
类似的也可以证明:
(a1,a2,a3,.....,an)=(a1,a1+a2,a1+a2+a3.....,a1+a2+......+an)
对于以上结论也有类似的结论:
(a1,a2,a3,.....,an)=(a1,a1−a2,a1−a2−a3.....,a1−a2−......−an)
同时有:
(a1,a2,a3,.....,an)=(a1,a2−a1,a3−a2.....,an−an−1)
第一种证明 :
我们可以利用结合率来一步步求即:
((a1,a1+a2),a1+a2+a3,a1+a2+a3+a4......,a1+a2+a3+...an)
可以将 a1,a2.....an写成dki的形式其中d为(a1,a2,.....,an)
即:
(d(k1,k1+k2),d(k1+k2+k3)......,d(k1,k2,k3....kn))
利用上述的结合率
因为(k1,k1,k2) 互质 所以 , 我们可以直接将 d(k1,k1+k2) 直接写成 d
对于后面的项:
(d∗1,d(k1+k2+k3)......,d(k1,k2,k3....kn))
因为 1 和任何数都互质 , 所以结果就是 d
另一种证明方式 :
我们来证 n = 3 时的情况:
即有 (a,b,c)=(a,a+b,a+b+c)
我们通过结合律可以得到:
(a , (a + b , a + b + c))
再由 (a , b) = (a , b - a)
我们可以先得到 (a , (a + b , a + b + c - a - b))
---> (a, a+b,c)
------> ( (a , a + b) , c) 同理
-------> (a , b , c)
到此得证!
n = 4 , 5 , 6 ...... m 都可以类似证明!
6 . 单调性:
这个性质比较有意思!描述的东西就是区间 [L , R] 的gcd 一定会小于等于区间[L , R + d]
因为我们每次加入一个数, gcd都可能被丢掉一个因数 , 所以gcd 是有区间单调性的。
形式化表达:
gcd([L,R])>=gcd([L,R+d]),其中0<=d
这时候如果询问区间gcd的话 , 就可以利用二分。
lcm
lcm 全称是 Least common multiple ,即最小公倍数
lcm(a,b) 形式化表达:
对于任意的一个自然数 a , b 由唯一分解定理都可以表示成这样的形式
a=p1k1 ⋅ p2k2 ⋅ p3k3 ⋅ p4k4....... pnknb=p1l1 ⋅ p2l2 ⋅ p3l3 ⋅ p4l4....... pnln
那么我们的 lcm(a , b) 可以形式化表示成这样
lcm (a , b)=p1max(k1,l1) ⋅ p2max(k2,l2) ⋅ p3max(k3,l3)......pnmax(kn,ln)
举个例子:
a = 3
b = 8
lcm(a , b) = 24 // 公倍数
那么我们如何去求lcm(a , b) ? 其实我们发现gcd 和 lcm 一些性质 , 从lcm,gcd 的形式化表达中我们可以观察到最大最小幂数的取法 , 无论如何都是来自两个数中的。所以我们可以发现
lcm(a,b) ⋅ gcd(a,b)=a ⋅ b
证明:
p1max(k1,l1)+min(k1,l1) ⋅ p2max(k2,l2)+min(k2,l2) ⋅ p3max(k3,l3)+min(k3,l3)......pnmax(kn,ln)+min(kn,ln)=p1k1+l1 ⋅ p2k2+l2 ⋅ p3k3+l3 ⋅ p4k4+l4....... pnkn+ln
因为 max(ki,li)+min(ki,li)=ki+li (1<=i<=n)
所以上述等式一定成立!
特别地 ,当gcd(a , b) = 1 , 即 a , b 互质。
lcm(a,b)=a ⋅ b
快速求出lcm
因为gcd(a , b) 容易求出 , 所以可以通过等式直接求出lcm
即
lcm(a,b)=gcd(a,b)a⋅b
但是很多时候a⋅b非常容易溢出 , 例如 a = 1e8 , b = 1e12 如果直接求 a⋅b 那么直接会爆long long
那么我们可以利用乘法和除法的交换律
那么我们可以将公式交换成这样:
lcm(a,b)=gcd(a,b)a ⋅ b
代码如下:
int lcm(int a , int b){
return a / gcd(a , b) * b;
}