#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
int primes[N];
bool st[N];
int phi[N];
int cnt;
int n;
ll get_euler(int n){
phi[1] = 1;
for(int i = 2; i <= n; i++){
if(!st[i]){
primes[cnt++] = i;
phi[i] = i - 1;//与i互质的数的个数有i-1个,因i为质数
}
for(int j = 0; primes[j] <= n/i; j++){
st[primes[j]*i] = true;
if(i % primes[j] == 0){//如果primes[j]是i的最小质因子的话,则primes[j]的质因数在i中的质因数已出现
//phi(i) = i * (p_1-1)/p_1 * ... * (p_k - 1) / p_k;
//phi(i * primes[j]) = i*primes[j] * (p_1-1)/p_1 * ... * (p_k - 1) / p_k;
//phi(i * primes[j]) = phi(i) * primes[j];
phi[primes[j]*i] = phi[i] * primes[j];
break;
}
//说明primes[j]不是i的最小质因子。
//phi(i) = i * (p_1-1)/p_1 * ... * (p_k - 1) / p_k;
//phi(i * primes[j]) = i*primes[j] * (p_1-1)/p_1 * ... * (p_k - 1) / p_k * (p_j - 1)/p_j;
//phi(i * primes[j]) = phi(i) * primes[j] * ((p_j - 1)/p_j]);
//phi(i * primes[j]) = phi(i) * primes[j] * ((primes[j] - 1)/primes[j]);
phi[primes[j] * i] = phi[i] * (primes[j] - 1);
}
}
ll res = 0;
for(int i = 1; i <= n; i++){//1~n个数中每个数的欧拉函数之和
res += (1ll)*phi[i];
}
return res;
}
int main(){
scanf("%d",&n);
cout << get_euler(n) << endl;
return 0;
}
【acwing】874. 筛法求欧拉函数*
最新推荐文章于 2022-10-27 18:25:25 发布