现在我自己推不出来,看题解的。
http://blog.csdn.net/ZLH_HHHH/article/details/77587832
大概是考虑用经典的容斥写出答案的式子,考虑每个数对答案的贡献,然后需要反演一下算出贡献的式子。
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1000000,maxv=1000005,MOD=1000000007;
int n,fib[maxv],cnt[maxv],ctb[maxv],a[maxv],mu[maxv],p[maxv];
LL ans;
bool vis[maxv];
void get_mu(){
mu[1]=1;
for(int i=2;i<=N;i++){
if(!vis[i]) p[++p[0]]=i, mu[i]=-1;
for(int j=1;j<=p[0]&&(LL)i*p[j]<=N;j++){
vis[i*p[j]]=true;
if(i%p[j]==0){ mu[i*p[j]]=0; break; }
mu[i*p[j]]=-mu[i];
}
}
}
int Pow(LL a,LL b){
LL res=1;
for(;b;b>>=1,a=a*a%MOD) if(b&1) res=(res*a)%MOD;
return res;
}
LL get(LL a,LL b){
if(b>=0) return Pow(a,b);
return Pow(Pow(a,-b),MOD-2);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x; scanf("%d",&x);
if(x>=3) a[x]++;
}
for(int i=3;i<=N;i++)
for(int j=1;i*j<=N;j++) cnt[i]+=a[i*j];
get_mu();
for(int i=3;i<=N;i++)
for(int d=1;i*d<=N;d++) if(cnt[i*d]) ctb[i]+=mu[d];
fib[1]=1; for(int i=2;i<=N;i++) fib[i]=(fib[i-1]+fib[i-2])%MOD;
ans=1; for(int i=3;i<=N;i++)
ans=(ans*get(fib[i],ctb[i]))%MOD;
printf("%lld\n",ans);
return 0;
}