Description
给定n个正整数a1,a2,…,an,求
的值(答案模10^9+7)。
Input
第一行一个正整数n。
接下来n行,每行一个正整数,分别为a1,a2,…,an。
Output
仅一行答案。
Sample Input
3
6
10
15
Sample Output
1595
Solution
注意到(varphi)是积性函数,那么我们可以对其每一个质因子进行考虑,对于质数(p),设(a_i)中(p)的指数为(b_i),那么贡献就是:
[sum_{i_1=0}^{b_1}sum_{i_2=0}^{b_2}cdotssum_{i_n=0}^{b_n}varphi(p^{sum i})
]
化简一下,注意特判(1):
[egin{align}
&((sum_{i_1=0}^{b_1}sum_{i_2=0}^{b_2}cdotssum_{i_n=0}^{b_n}p^{sum i})-1)frac{p-1}{p}+1\
=&((prod_{i=1}^{n}sum_{j=0}^{b_i}p^j)-1)frac{p-1}{p}+1\
=&((prod_{i=1}^{n}frac{p^{b_i+1}-1}{p-1})-1)frac{p-1}{p}+1\
end{align}
]
然后答案就是:
[prod_{pin prime}((prod_{i=1}^{n}frac{p^{b_i+1}-1}{p-1})-1)frac{p-1}{p}+1
]
枚举质因子暴力算就好了。
时间复杂度(O(a+nlog a))。
#include<bits/stdc++.h>
using namespace std;
void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('
');}
#define lf double
#define ll long long
const int maxn = 2e5+10;
const int maxm = 1e7+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;
#define vec_iter vector<int > :: iterator
int qpow(int a,int x) {
int res=1;
for(;x;x>>=1,a=1ll*a*a%mod) if(x&1) res=1ll*res*a%mod;
return res;
}
int n,a[maxn],vis[maxm],pri[maxm],tot,mx,lst[maxm];
vector<int > cnt[maxm];
int main() {
read(n);for(int i=1;i<=n;i++) read(a[i]),mx=max(mx,a[i]);
lst[1]=1;
for(int i=2;i<=mx;i++) {
if(!vis[i]) pri[++tot]=i,lst[i]=i;
for(int j=1;j<=tot&&i*pri[j]<=mx;j++) {
vis[i*pri[j]]=1;lst[i*pri[j]]=pri[j];
if(i%pri[j]==0) break;
}
}
for(int i=1;i<=n;i++) {
int pre=0,c=0;
while(a[i]!=1) {
if(pre!=0&&pre!=lst[a[i]]) cnt[pre].push_back(c),c=0;
pre=lst[a[i]],a[i]/=lst[a[i]],c++;
}cnt[pre].push_back(c);
}
int ans=1;
for(int i=1;i<=tot;i++) {
int res=1,p=pri[i];
if(cnt[p].empty()) continue;
for(vec_iter it=cnt[p].begin();it!=cnt[p].end();it++)
res=1ll*res*(qpow(p,(*it)+1)-1)%mod*qpow(p-1,mod-2)%mod;
res=1ll*(res-1)*(p-1)%mod*qpow(p,mod-2)%mod;
ans=1ll*ans*(res+1)%mod;
}
write(ans);
return 0;
}