6.1.6 欧拉函数及其性质

欧拉函数及其性质

定义

\(1 \sim N\) 中与 \(N\) 互质的数的个数,被称为欧拉函数,记作 \(\varphi(N)\)phi

如果 \(n\) 是个质数,那么 \(\varphi(n) = n - 1\)

如果 \(n\) 是素数的 \(k\) 次幂,即 \(n = p^k\) ,那么 \(\varphi(n) = p^k - p^{k - 1}\) ,除了 \(p\) 的倍数外,其他的数都和 \(n\) 互质

根据唯一分解定理,将 \(n\) 分解 \(n = p_1^{k_1} \times p_2^{k_2}\times \cdots \times p_m^{k_m}\)

则有

\[\varphi(n) = n \times \prod_{p \mid n} (1 - \frac 1 p) \]

因为欧拉函数为积性函数

\[\begin{align} \varphi(n) &= \varphi(p_1^{k_1} \times p_2^{k_2}\times \cdots \times p_m^{k_m}) \\ &= \varphi(p_1^{k_1}) \times \varphi(p_2^{k_2}) \times \cdots \times \varphi(p_m^{k_m}) \\ &= (p_1^{k_1} - p_1^{k_1 - 1}) \times (p_2^{k_2} - p_2^{k_2 - 1}) \times \cdots \times (p_m^{k_m} - p_m^{k_m - 1}) \\ &=n \times(1 - \frac 1 {p_1}) \times(1 - \frac 1 {p_2}) \times \cdots \times(1 - \frac 1 {p_m}) \\ &= n \times \prod_{p \mid n} (1 - \frac 1 p) \end{align} \]

有了这个性质,我们就可以 \(O(\sqrt n)\) 求解单个数的欧拉函数

int get_phi (int n) {
    int ans = n;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            ans = ans / i * (i - 1);
            while (n % i == 0) n /= i;
        }
    }
    if (n > 1) ans = ans / n * (n - 1);
    return ans;
}

欧拉函数的性质

性质1:积性函数,即在 \(\gcd(a, b) = 1\) 时,有 \(\varphi(ab) = \varphi(a) \times \varphi(b)\)

性质2:当 \(n > 2\)\(\varphi(n)\) 是偶数,也就是与 \(n\) 互质的数成对出现

性质3:\(\forall n > 1\)\(1 \sim n\) 中与 \(n\) 互质的数的和为 \(n \times \frac {\varphi(n)} 2\)

性质4:\(\displaystyle \sum_{d \mid n} \varphi(d) = n\)

用线性筛可以 \(O(N)\) 求出 \(1 \sim N\) 的欧拉函数,设 \(x\) 为我们当前要求的值

  • 如果 \(x\) 是个质数 \(\varphi(x) = x - 1\)
  • 如果 \(pri[j] \mid i\) 那么说明 \(i\)\(x\) 的所有质因子

\[\begin{align} \varphi(x) &= x \times \prod_{p \mid x} (1 - \frac 1 p) \\ &= pri[j] \times i \times \prod_{p \mid x} (1 - \frac 1 p) \\ &= pri[j] \times \varphi(i) \end{align} \]

  • 如果 \(pri[j] \not \mid i\) 那么可以利用积性函数性质 \(\varphi(x) = \varphi(pri[j]) \times \varphi(i)\)
void primes (int n) {
    phi[1] = 1;
    for (int i = 2; i <= n; i++) {
        if (!v[i]) {
            v[i] = i;
            pri[++cnt] = i;
            phi[i] = i - 1;
        }
        for (int j = 1; pri[j] * i <= n && j <= cnt; j++) {
            v[pri[j] * i] = 1;
            if (i % pri[j] == 0) {
                phi[pri[j] * i] = pri[j] * phi[i];
                break;
            }
            phi[pri[j] * i] = (pri[j] - 1) * phi[i];
        }
    }
}

例题

仪仗队

posted @ 2025-08-11 10:22  michaele  阅读(43)  评论(0)    收藏  举报