由于φ函数的积性,我们可以统计每一个质数p的答案,然后再累乘起来。
对于质数p,我们求出ai中质因数p的次数bi,那么答案为:
最后将每一次的答案乘起来就好了。
AC代码如下(为什么我前面还有一个0msT_T):
#include<iostream>
#include<cstdio>
#include<algorithm>
#define mod 1000000007
#define ll long long
using namespace std;
int n,cnt,c[3505],sum[105]; bool vis[2505];
struct node{ int x,y; }a[800005];
bool cmp(node aa,node bb){ return aa.x<bb.x || aa.x==bb.x && aa.y<bb.y; }
void dps(int x){
int i;
for (i=1; c[i]*c[i]<=x; i++) if (!(x%c[i])){
a[++cnt].x=c[i]; a[cnt].y=0;
while (!(x%c[i])){ x/=c[i]; a[cnt].y++; }
}
if (x>1){ a[++cnt].x=x; a[cnt].y=1; }
}
void pfs(){
int i,j;
for (i=2; i<=3500; i++){
if (!vis[i]) c[++c[0]]=i;
for (j=1; j<=c[0] && i*c[j]<=3500; j++){
vis[i*c[j]]=1;
if (!(i%c[j])) break;
}
}
}
int ksm(int x,int y){
int t=1; for (; y; y>>=1,x=(ll)x*x%mod) if (y&1) t=(ll)t*x%mod; return t;
}
int main(){
scanf("%d",&n); int i; pfs();
for (i=1; i<=n; i++){
int x; scanf("%d",&x); dps(x);
}
sort(a+1,a+cnt+1,cmp);
int ans=1,j,k,p;
for (i=1; i<=cnt; i=j+1){
for (j=i; a[j+1].x==a[i].x && j<cnt; j++);
p=a[i].x; sum[0]=1;
for (k=1; k<=a[j].y; k++)
sum[k]=(ll)sum[k-1]*p%mod;
for (k=1; k<=a[j].y; k++)
sum[k]=(sum[k-1]+sum[k])%mod;
int tmp=1;
for (k=i; k<=j; k++) tmp=(ll)tmp*sum[a[k].y]%mod;
tmp=(ll)(tmp-1)*(p-1)%mod*ksm(p,mod-2)%mod+1;
ans=(ll)ans*tmp%mod;
}
printf("%d\n",ans);
return 0;
}
by lych
2016.2.23