求欧拉函数
n
项(试除法)
求欧拉函数第原理
见《进阶指南》第145
页。
代码
int phi (int x) {
int res = x;
for (int i = 2; i <= x / i; ++ i) {
if (x % i == 0) {
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
}
if (x > 1) res = res / x * (x - 1);
return res;
}
n
项(线性筛)
求欧拉函数前原理
见《进阶指南》第147
页。
代码
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 1000010;
int n;
int idx, primes[N], phi[N];
bool mark[N];
void get_phi (int n) {
phi[1] = 1;
for (int i = 2; i <= n; ++ i) {
if (mark[i] == false) {
primes[++ idx] = i;
phi[i] = i - 1;
}
for (int j = 1; primes[j] <= n / i; ++ j) {
mark[i * primes[j]] = true;
if (i % primes[j] == 0) {
phi[i * primes[j]] = phi[i] * primes[j];
break;
} else {
phi[i * primes[j]] = phi[i] * (primes[j] - 1);
}
}
}
}
int main () {
cin >> n;
get_phi(n);
LL res = 0;
for (int i = 1; i <= n; ++ i)
res += phi[i];
cout << res << endl;
return 0;
}