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; }