给定一个正整数n,求1~n中每个数的欧拉函数之和。
输入格式
共一行,包含一个整数n。
输出格式
共一行,包含一个整数,表示1~n中每个数的欧拉函数之和。
数据范围
1≤n≤106
输入样例:
6
输出样例:
12
想法:
涉及到在范围内的质数,则使用线性筛法
#include<iostream>
using namespace std;
const int N=1e6+10;
typedef long long LL;
bool st[N];
int prim[N],phi[N];
int cnt=0;
LL get(int x){
phi[1]=1;
for(int i=2;i<=x;i++){ //求1~n的质数
if(!st[i]) {
prim[cnt++]=i;
phi[i]=i-1; //质数和质数前面的数全都互质
}
for(int j=0;prim[j]<=x/i;j++){ //在质数内查找
st[prim[j]*i] = true;
if(i%prim[j]==0) {
//此时pj是i的最小质因子
//所以也是pj*i的最小质因子
//f(i*pj)=i*pj*(pj-1)/pj*....
//f(i)=i*(pj-1)/pj*....
//所以f(i*pj) = pj*f(i)
phi[i*prim[j]]=phi[i]*prim[j];
break;
}else{
//此时pj是pj*i的最小质因子,但是不是i的质因子
//f(i*pj) = i*pj*(pj-1)/pj*....
//f(i)=i*....
//所以f(i*pj) = f(i)*(pj-1)
}phi[i*prim[j]]=phi[i]*(prim[j]-1);
}
}
LL res=0;
for(int i=1;i<=x;i++){ //需要枚举每个数的欧拉函数求和
res+=phi[i];
}
return res;
}
int main(){
int n;
cin>>n;
printf("%lld\n", get(n));
return 0;
}