标签:mil mod 公倍数 bsp while循环 archive text ora 公约数
gcd即最大公约数,lcm即最小公倍数。
首先给出a×b=gcd×lcm
证明:令gcd(a,b)=k,a=xk,b=yk,则a×b=x*y*k*k,而lcm=x*y*k,所以a*b=gcd*lcm。
所以求lcm可以先求gcd,而求gcd的方法就是辗转相除法,也叫做欧几里德算法,核心为gcd(m,n)=gcd(n,m%n)
证明:令 k=gcd(m,n),则 k|m 并且 k|n;
令 j=gcd(n, m mod n), 则j|n 并且 j|(m mod n);
对于m, 可以用n 表示为 m=pn+(m mod n);
由引理可知 j|m(其中 x=p,y=1), 又 j|n,于是 j 是 m 和 n 的公约数(但不一定是最大的);
因为 k 是 m 和 n 的最大公约数,所以必有 k≥j;
通过另一种表示形式:(m mod n)=m-pn,同理可得:
k|(m mod n),又k|n,于是 k 是 (m mod n) 和 n 的公约数(也不一定是最大的);
同样由 j 是 n 和 (m mod n) 的最大公约数可以得到 j≥k;
由常识,得出结论 k=j,
即gcd(m,n) = gcd(n, m mod n) ,得证。
代码实现:
while循环:
1 LL gcd(LL a, LL b){ 2 LL t; 3 while(b){ 4 t = b; 5 b = a % b; 6 a = t; 7 } 8 return a; 9 }
递归:
1 LL gcd(LL a, LL b){ 2 return b ? gcd(b, a%b) : a; 3 }
求lcm=a*b/gcd即可,但碰到一些恐怖的数据可能会溢出,应改成lcm=a/gcd*b。
最后给出一些公式:
gcd(ka, kb) = k * gcd(a, b)
lcm(ka, kb) = k * lcm(a, b)
lcm(S/a, S/b) = S/gcd(a, b)
参考:https://www.cnblogs.com/ider/archive/2010/11/16/gcd_euclid.html
https://www.cnblogs.com/linyujun/p/5167914.html
标签:mil mod 公倍数 bsp while循环 archive text ora 公约数
原文地址:https://www.cnblogs.com/FrankChen831X/p/10526233.html