题解:
对于fib数列有
gcd(fi,fj)=fgcd(i,j)
gcd
(
f
i
,
f
j
)
=
f
gcd
(
i
,
j
)
(可用归纳法证明)。
那么对于
gcd(f{T})
gcd
(
f
{
T
}
)
显然等于
fgcd{T}
f
gcd
{
T
}
。
怎么求lcm? 直接min-max对指数容斥即可,易得:
为了消掉gcd,我们用Mobius反演(乘法意义下),构造 g g ,使得,那么 gn=fn∏d|n,d≠ng−1d g n = f n ∏ d | n , d ≠ n g d − 1 或者 gn=∏d|nfμ(nd)d g n = ∏ d | n f d μ ( n d ) 。
那么有:
显然如果有任意一个数 ai a i 使得整除 d|ai d | a i ,那么最后 gd g d 会被计算1次。 直接看哪些 gd g d 有倍数然后乘起来就好了。
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+50, mod=1e9+7;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (long long)x*y%mod;}
inline int power(int a,int b,int rs=1) {for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a); return rs;}
int n,a[N],mx,fib[N],g[N],ok[N];
int main() {
cin>>n; for(int i=1;i<=n;i++) cin>>a[i], mx=max(mx,a[i]), ok[a[i]]=1;
fib[1]=1; for(int i=2;i<=mx;i++) fib[i]=add(fib[i-1],fib[i-2]);
for(int i=1;i<=mx;i++) g[i]=fib[i];
int ans=1;
for(int i=1;i<=mx;i++) {
const int inv=power(g[i],mod-2);
for(int j=2;j*i<=mx;j++) g[i*j]=mul(g[i*j],inv);
}
for(int i=1;i<=mx;i++)
for(int j=1;j*i<=mx;j++)
if(ok[i*j]) {ans=mul(ans,g[i]); break;}
cout<<ans<<endl;
}