原题链接:http://www.51nod.com/Challenge/Problem.html#problemId=1355
题目大意:
定义斐波那契数列 f0=0,f1=1,fn=fn−1+fn−2 (n≥2),现给出 n 个整数 {ai},求出 lcm(fa1,fa2,⋯,fan)
斐波那契最大公约数引理:gcd(fn,fm)=fgcd(n,m)
要证明这个引理,我们需要注意到一些性质:
性质 1:gcd(fn,fn−1)=1 对于 n≥1 成立
对于数列,因为有递推公式,与归纳法的结构很相似,因此首先考虑归纳。
当 n=1 时,gcd(fn,fn−1)=1
当 n>1 时,gcd(fn,fn−1)=gcd(fn−1+fn−2,fn−1)=gcd(fn−2,fn−1)=1
性质 2:fn+m=fn−1fm+fnfm+1
同样考虑归纳,对于这类有多个变量的,只需要挑选一个变量归纳即可,在这里对 m 归纳。
当 m=0 时,fn=fn×1
当 m=1 时,fn+1=fn−1+fn
当 m>1 时,fn+m=fn+m−2+fn+m−1=fn−1(fm−2+fm−1)+fn(fm−1+fm)=fn−1fm+fnfm+1
有了以上两个性质,我们就能够来证明引理了。
gcd(fn+m,fm)=gcd(fn−1fm+fnfm+1,fm)=gcd(fnfm+1,fm)=gcd(fn,fm)
其中第一步用了性质 2,最后一步用了性质 1(合理性证明可以利用具体数学中讲到的,考察每个素因子的次数)。这样我们通过辗转相除法的步骤,即可归纳证明引理成立。
回原题,我们要求 lcm(fS),而 lcm 并不是我们所熟悉的形式,需要想办法转换到 gcd 上去。还记得吗?在两元运算中,lcm(a,b)×gcd(a,b)=ab,但是很遗憾,这种做法不能拓展到多元。多元情况只能两两合并,这样会爆模数,于是,我们只能另寻它法。
换一个视角,lcm 就是对于每个素因子的次数求 max,而 gcd 就是对于每个素因子的次数求 min,这样就能和 min−max 容斥相联系了!回顾 min−max 容斥的公式:
max(S)=∑T⊆S(−1)|T|−1min(T)
运用到 lcm 和 gcd 当中(定义 p 为素数,Sp 表示 S 中每个元素包含的最大的 p 次幂的新集合)
lcm(S)=∏ppmax(Sp)=∏pp∑T⊆S(−1)|T|−1min(Tp)=∏T⊆S(∏ppmin(Tp))(−1)|T|−1=∏T⊆Sgcd(T)(−1)|T|−1
将 S 集合在套上 f 的意义下操作(证明同理,唯一区别是在最后一步用了引理),知:
lcm(fS)=∏T⊆Sf(−1)|T|−1gcd(T)
这样算根本没有得到简化,巧妙的一步来了,我们尝试将 fgcd 拆开,构造一个函数 g,使得 fn=∏d∣ngd,则:
lcm(fS)=∏T⊆S⎛⎝∏d∣gcd(T)gd⎞⎠(−1)|T|−1=∏dg∑T⊆S[d∣gcd(T)](−1)|T|−1d
考虑每个 gd 的指数部分,假设 S 中有 t 个数(t>0)整除于 d,则指数等于:
t∑i=1(−1)i−1(ti)=1−t∑i=0(−1)i(ti)=1
所以问题转化为了:
lcm(fS)=∏∃x∈S,d∣xgd
最后一个没有解决的问题就是如何构造这样的 g,有两种方法(其实是本质相同的):
第一种,简单朴素,利用递推:
gn=fn∏d∣n,d≠ngd
第二种,观察到这个形式是乘法版的狄利克雷卷积,于是我们可以尝试改造一下莫比乌斯反演:
回顾莫比乌斯反演:
fn=∑d∣ngn⇔gn=∑d∣nμ(nd)fd
若要改造成乘法,很简单,两边取对数即可!
lnfn=∑d∣nlngd⇔lngn=∑d∣nμ(nd)lnfdgn=e∑d∣nμ(nd)lnfd=∏d∣nfμ(nd)d
综上,总时间复杂度为 O(nlogn)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】