[BZOJ3560] DZY Loves Math V

Description

给定n个正整数a1,a2,…,an,求

img

的值(答案模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;
}
posted @ 2019-03-24 16:53  Hyscere  阅读(172)  评论(0编辑  收藏  举报