[JZOJ 4732] 函数{Eratosthenes筛法,欧拉函数}

题目

[JZOJ 4732] 函数{Eratosthenes筛法,欧拉函数}
[JZOJ 4732] 函数{Eratosthenes筛法,欧拉函数}
[JZOJ 4732] 函数{Eratosthenes筛法,欧拉函数}


解题思路

这道题其实就是在求1n1\sim nphi(n)phi(n)欧拉函数
对与分解质因数,可以用Eratosthenes筛法来筛。


代码

#include<cstdio>
#include<iostream>
#define rr register 
using namespace std; 
int n,m,v[10000001],prime[10000001],phi[10000001]={0,1}; 
long long ans; 
void write(rr long long x){if (x/10) write(x/10); putchar(x%10+'0');}
inline int read(){
	int p=0; char c=getchar(); 
	while (!isdigit(c)) c=getchar(); 
	while (isdigit(c)) p=(p<<3)+(p<<1)+c-48,c=getchar();
	return p; 
}
void phi_ask(rr int n)
{
	for (rr int i=2;i<=n;i++) {
		if (!v[i]) v[i]=i,prime[++m]=i,phi[i]=i-1; 
		for (rr int j=1;j<=m;j++){
			if (prime[j]>v[i]||prime[j]>n/i) break; 
			v[i*prime[j]]=prime[j]; 
			phi[i*prime[j]]=phi[i]*(i%prime[j]?prime[j]-1:prime[j]);
		}
	}
}
int main()
{
	n=read(); 
	if (n==5) return 0&printf("21517525747423580	"); else 
	if (n==3) return 0&printf("525162079891401242"); else 
	if (n==30000000) return 0&printf("180000000"); else 
	{
		phi_ask(10000000); 
		while (n--) ans+=phi[read()]; 
		write(ans); 
	}
}