筛法求解欧拉函数 & 莫比乌斯函数

回顾

欧拉函数 \(\varphi(x)\) 的定义 : \(1 \sim x\) 里面, 有多少个正整数和 \(x\) 互质。


【莫比乌斯与欧拉】STD

// 2026-07-21
#include <bits/stdc++.h>

using namespace std;

/* O(n) 求 1 ~ n 每个数的莫比乌斯函数和欧拉函数 */
const int N = 1E6 + 5;

int phi[N], mu[N], primes[N], tot;
bool vis[N];

void get() {
    phi[1] = mu[1] = 1;

    for (int i = 2; i < N; i++) {
        if (!vis[i]) {
            phi[i] = i - 1;
            mu[i] = -1;
            primes[++tot] = i;
        }

        for (int j = 1; j <= tot && i * primes[j] < N; j++) {
            vis[i * primes[j]] = true;
//          primes[j] 是 i * primes[j] 的最小质因子
            if (i % primes[j] == 0) {
/*              i = k * primes[j]
                i * primes[j] = k * primes[j] * primes[j]
                相对于 i 来讲, primes[j] 不是 i * primes[j] 的一种新的质因子
*/
                mu[i * primes[j]] = 0;
                phi[i * primes[j]] = phi[i] * primes[j];
                break;
            }
            // 相对于 i 来讲, primes[j] 是 i * primes[j] 的一种新的质因子
            phi[i * primes[j]] = phi[i] * (primes[j] - 1);
            mu[i * primes[j]] = -mu[i];
            
/*          mu[i] = 0, mu[i * primes[j]] = 0;
            mu[i] != 0, mu[i * primes[j]] = -mu[i];
*/
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    get();
    
    int n, T;
    cin >> n >> T;

    int opt, x;
    while (T--) {
        cin >> opt >> x;
        if (opt == 1) {
            cout << mu[x] << "\n";
        } else {
            cout << phi[x] << "\n";
        }
    }
    return 0;
}
posted @ 2026-07-21 13:48  Smash1  阅读(1)  评论(0)    收藏  举报