一、什么是欧拉函数

定义:
\(ϕ(x)\)表示\(x\)的欧拉函数值,代表了从\(1\)到\(x\)与\(x\)互质的数的个数,例如\(ϕ(8)=4\) 因为\(1,3,5,7\)均和\(8\)互质。

二、欧拉函数的通项公式

$\large φ(n)=n*(1-\frac{1}{p_1})(1-\frac{1}{p_2})(1-\frac{1}{p_3})*(1-\frac{1}{p_4})……(1-\frac{1}{p_n})$

其中\(p_1, p_2……p_n\)为\(n\)的所有质因数,\(n\)是不为\(0\)的整数。\(φ(1)=1\)(唯一和\(1\)互质的数就是\(1\)本身)。

三、求单个数字的欧拉函数

#include <bits/stdc++.h>

using namespace std;

/**
 * 功能:欧拉函数
 * @param x
 * @return
 */
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;
}

int main() {
    cout << phi(2) << endl;
    cout << phi(8) << endl;
    return 0;
}

四、筛法求欧拉函数

#include <bits/stdc++.h>

using namespace std;

const int N = 1010;
int primes[N];  //保存的是每一个质数
int cnt;        //cnt代表质数下标,就是到第几个了
int phi[N];     //欧拉函数值
bool st[N];     //是不是已经被筛掉了
//  求1-N之间每一个数的欧拉函数
//  线性筛法求质数的过程当中,捎带着求出每个数的欧拉函数值,其实还可以顺便求出很多东西。
void 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++) {
            int t = primes[j] * i;
            st[t] = true;
            if (i % primes[j] == 0) {
                phi[t] = phi[i] * primes[j];
                break;
            } else {
                phi[t] = phi[i] * (primes[j] - 1);
            }
        }
    }
}

int main() {
    get_eulers(1000);
    for (int i = 1; i <= 1000; i++)
        cout << i << ":" << phi[i] << endl;
    return 0;
}