辗转相除法求gcd
定理:
gcd(a,b)=gcd(b,a mod b)
证明:令
c=gcd(a,b),不妨设
a=mc,b=nc,gcd(m,n)=1
再设
a=k×b+r
则
r=mc−knc=(m−kn)×c
所以
c也是
r的因数
所以
gcd(b,a mod b)=gcd(b,k)=gcd(nc,(m−kn)c)=c
由于
gcd(m,n)=1
所以
gcd(n,m−kn)=1
所以
gcd(a,b)=gcd(b,a mod b)=c
Code
void gcd(int a,int b){
return (a%b==0)?b:gcd(b,a%b);
时间复杂度
由于每次
a至少减少一半,所以最大时间复杂度为
O(logn)。
值得一提的是,对于上述函数,其运行最慢的数据为著名的
fibonacci数列,原因也很简单,因为每次
a mod b都会使
a刚好减少一半多一点。
求lcm
由公式得
gcd(i,j)∗lcm(i,j)=i∗j
所以
lcm(i,j)=gcd(i,j)i∗j
公式证明也很简单,从质因子的方向可以方便证明