求欧拉函数

AcWing-847-筛法求欧拉函数open in new window

求欧拉函数第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;
}
最后修改于: