874. 筛法求欧拉函数
欧拉函数的定义
给定一个正整数n,请你求出1~n中质数的个数。
如果要求1 ~ N里每个数的欧拉函数,用公式要求每一个数的质因子,很慢,复杂度为
用筛质数的方法可以在时间内计算出每个数的欧拉函数。
phi[primes[j] * i]
分为两种情况:
①i % primes[j] == 0
时:primes[j]
是i
的最小质因子,也是primes[j] * i
的最小质因子,因此1 - 1 / primes[j]
这一项在phi[i]
中计算过了,只需将基数N
修正为phi[i] * primes[j]
。
② i % primes[j] != 0
:primes[j]
不是i
的质因子,只是primes[j] * i
的最小质因子,因此不仅需要将基数N
修正为primes[j]
倍,还需要补上1 - 1 / primes[j]
这一项,因此最终结果phi[i] * (primes[j] - 1)
。
#include<iostream>
using namespace std;
typedef long long LL;
const int N=1000010;
int phi[N],cnt;
int primes[N];
bool st[N];
LL get_eulers(int n){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!st[i]){
primes[cnt++]=i;
phi[i]=i-1;
}
for(int j=0;primes[j]<=n/i;j++){
st[primes[j]*i]=true;
if(i%primes[j]==0){
phi[i*primes[j]]=phi[i]*primes[j];
break;
}
phi[i*primes[j]]=phi[i]*(primes[j]-1);
}
}
LL res=0;
for(int i=1;i<=n;i++) res+=phi[i];
return res;
}
int main(){
int n;
scanf("%d",&n);
cout<<get_eulers(n);
return 0;
}