小岛【】发了篇日志,说一个问题。
求
lcm(fib(a1),fib(a2),...,fib(an))mod(109+7)
。
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1355
https://www.hackerrank.com/contests/infinitum10/challenges/fibonacci-lcm
https://www.codechef.com/problems/FLCM/
https://www.hackerrank.com/contests/infinitum9/challenges/fibonacci-gcd/editorial
最后的是问题的解决,然而是个英文的。
那么我具体的解释解释……
总而言之是先解决
gcd(...)
,然后喜闻乐见的:
lcm=fac/gcd
。
而解决
gcd
的关键是这样一个公式:
gcd(fib(a),fib(b))=fib(gcd(a,b))
这个属于 fib 数的常见性质。 Acdreamer 大大的博客上有过记载: http://blog.csdn.net/acdreamers/article/details/7909480
它的证明也不复杂。这里就介绍一下。
有这样的关系:
(1110)n=(fibn+1fibnfibnfibn−1)
那么:
(1110)a+b=(fiba+b+1fiba+bfiba+bfiba+b−1)
(1110)a+b=(fiba+1fibafibafiba−1)(fibb+1fibbfibbfibb−1)
这样就有了:
fib(a+b)=fin(a+1)fib(b)+fib(a)fib(b−1)
gcd(fib(a),fib(b)) 在 a>b 的状况下把 fib(a) 写作 fib(a−b+b) ,利用上面的公式得到:
gcd(fib(a),fib(b))=gcd(fib(a−b)fib(b−1),fib(b))
然而我们有:
gcd(fib(b),fib(b−1))=gcd(fib(b−2),fib(b−1))=gcd(fib(b−1),fib(b−2))=...=gcd(1,0)=1
其中总结到的 gcd(fib(n),fib(n−1))=1 也是值得注意的性质。
于是我么得到了:
gcd(fib(a),fib(b))=gcd(fib(b),fib(a−b))
迭代上面式子的过程若干次,就可以得到:
gcd(fib(a),fib(b))=gcd(fib(b),fib(a mod b))
我们发现了这样的格式:
f(a,b)=fib(a),b=0f(a,b)=f(b,a mod b),else
欧几里得算法告诉我们:
gcd(fib(a),fib(b))=fib(gcd(a,b))
详细来说就是:
fib−1⋅f(a,b)=a,b=0fib−1⋅f(a,b)=fib−1⋅f(b,a mod b),else
说明
fib−1⋅f(a,b)=gcd(a,b)
f(a,b)=fib(gcd(a,b))