[BZOJ3560] DZY Loves Math V
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}\cdots\sum_{i_n=0}^{b_n}\varphi(p^{\sum i})
\]
化简一下,注意特判\(1\):
\[\begin{align}
&((\sum_{i_1=0}^{b_1}\sum_{i_2=0}^{b_2}\cdots\sum_{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_{p\in prime}((\prod_{i=1}^{n}\frac{p^{b_i+1}-1}{p-1})-1)\frac{p-1}{p}+1
\]
枚举质因子暴力算就好了。
时间复杂度\(O(a+n\log 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('\n');}
#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;
}