BZOJ3560 : DZY Loves Math V

因为欧拉函数是非完全积性函数,所以可以考虑对每个数进行分解质因数,将每个质数的解乘起来即可。

对于一个质数$p$,设它在各个数中分别出现了$b_1,b_2,...b_n$次,那么由生成函数和欧拉函数的性质得,它对答案的贡献为:

\[(\prod_{i=1}^n\frac{p^{b_i+1}-1}{p-1}-1)\times\frac{p-1}{p}+1\]

#include<cstdio>
const int N=10000010,P=1000000007;
int n,m,i,j,a[100010],tot,p[N],v[N],cnt[N],r[N],f[N],ans=1;
inline void divide(int n){
tot=0;
while(n>1){
if(!cnt[v[n]])p[tot++]=v[n];
cnt[v[n]]++,n/=v[n];
}
for(int i=0;i<tot;i++){
int j=p[i],t=j;
while(cnt[j])t=1LL*t*j%P,cnt[j]--;
f[j]=1LL*(t-1)*r[j-1]%P*f[j]%P;
}
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]>m)m=a[i];
}
for(r[0]=r[1]=1,i=2;i<=m;i++){
r[i]=(-1LL*r[P%i]*(P/i)%P+P)%P;
if(!v[i])p[tot++]=v[i]=i,f[i]=1;
for(j=0;j<tot;j++){
if(i*p[j]>m)break;
v[i*p[j]]=p[j];
if(i%p[j]==0)break;
}
}
for(i=1;i<=n;i++)divide(a[i]);
for(i=2;i<=m;i++)if(v[i]==i)ans=(1LL*(f[i]+P-1)*(i-1)%P*r[i]+1)%P*ans%P;
return printf("%d",ans),0;
}

  

上一篇:QT信号槽机制


下一篇:非Qt工程使用Qt的信号槽机制