欧拉函数

欧拉函数 $\varphi(n)$ 统计 $1$ 到 $n$ 中有多少个数与 $n$ 互质。

一句话算法

欧拉函数 φ(n)\varphi(n) 统计 11nn 中有多少个数与 nn 互质。

问题模型

给定一个正整数 nn,求:

φ(n)={x1xn,gcd(x,n)=1} \varphi(n)=|\{x\mid 1\le x\le n,\gcd(x,n)=1\}|

例如 n=6n=6 时,1,51,566 互质,所以:

φ(6)=2 \varphi(6)=2

核心直觉

一个数 xxnn 不互质,当且仅当它被 nn 的某个质因子整除。

如果:

n=p1a1p2a2pkak n=p_1^{a_1}p_2^{a_2}\cdots p_k^{a_k}

那么要从 1..n1..n 中删掉所有被 p1,p2,,pkp_1,p_2,\ldots,p_k 整除的数。用容斥整理后得到公式:

φ(n)=ni=1k(11pi) \varphi(n)=n\prod_{i=1}^{k}\left(1-\frac1{p_i}\right)

注意,公式只关心“有哪些不同质因子”,不关心每个质因子的次数。

算法步骤

  1. 令答案 ans = n
  2. p = 2 开始试除到 n\sqrt n
  3. 如果 p 能整除当前 n
    • 说明 p 是原数的一个质因子;
    • 更新 ans = ans / p * (p - 1)
    • 把当前 n 中所有因子 p 除干净。
  4. 循环结束后,如果 n > 1,说明剩下一个大质因子,再做一次:
    • ans = ans / n * (n - 1)
  5. 输出 ans

算法证明

nn 的不同质因子为 p1,p2,,pkp_1,p_2,\ldots,p_k

  1. 不互质的判定

    xxnn 不互质,等价于 xx 至少含有一个 pip_i 作为因子。

  2. 保留下来的比例

    1..n1..n 中,pip_i 的倍数占 1pi\frac1{p_i}。删掉这些倍数后,保留比例为:

    11pi 1-\frac1{p_i}
  3. 多个质因子的容斥

    对所有不同质因子做容斥,保留下来的数量为:

    ni=1k(11pi) n\prod_{i=1}^{k}\left(1-\frac1{p_i}\right)
  4. 代码等价

    对每个质因子 pp,代码执行:

    ansans÷p×(p1) ans \leftarrow ans\div p\times(p-1)

    这正是把当前答案乘上 (11p)\left(1-\frac1p\right) 的整数写法。

所以算法正确计算了 φ(n)\varphi(n)

复杂度分析

试除法最多枚举到 n\sqrt n,时间复杂度为 O(n)O(\sqrt n)

空间复杂度为 O(1)O(1)

如果需要求 1..N1..N 的所有欧拉函数值,应使用线性筛递推,不能对每个数单独试除。

代码实现

cpp
        
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <bits/stdc++.h> using namespace std; long long euler_phi(long long n) { long long ans = n; for (long long p = 2; p * p <= n; p++) { if (n % p != 0) continue; ans = ans / p * (p - 1); while (n % p == 0) n /= p; } if (n > 1) ans = ans / n * (n - 1); return ans; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); long long n; cin >> n; cout << euler_phi(n) << '\n'; return 0; }

测试用例

输入:

36

输出:

12

解释:

36=22×32 36=2^2\times3^2

所以:

φ(36)=36(112)(113)=12 \varphi(36)=36\left(1-\frac12\right)\left(1-\frac13\right)=12

应用分类详解

欧拉函数的本质是统计模 nn 意义下的可逆元素数量。

一、互质计数

典型模式: 题目要求统计 1..n1..n 中与 nn 互质的数。

识别信号: 出现“互质个数”“小于等于 n 且 gcd 为 1”。

核心建模:nn 分解质因子,套欧拉函数公式。

应用场景 经典题目 核心思路
单点互质计数 luogu-P2303 试除质因子求 φ(n)\varphi(n)
互质对统计 luogu-P2158 枚举分母时用欧拉函数计数

二、模意义下的可逆元素

典型模式: 判断模 nn 下哪些数有乘法逆元。

识别信号: 出现“逆元”“剩余类”“与模数互质”。

核心建模:nn 下有逆元的数正好是与 nn 互质的数,因此数量是 φ(n)\varphi(n)

应用场景 经典题目 核心思路
逆元存在性 模运算题 gcd(a,n)=1 才存在逆元
剩余类群大小 数论证明题 可逆剩余类个数为 φ(n)\varphi(n)

三、欧拉定理与指数降幂

典型模式: 大指数取模,并且底数与模数互质。

识别信号: 出现 abmodma^b\bmod m,指数极大,且需要利用周期。

核心建模:gcd(a,m)=1\gcd(a,m)=1,则:

aφ(m)1(modm) a^{\varphi(m)}\equiv1\pmod m

可以用 φ(m)\varphi(m) 处理指数周期。

应用场景 经典题目 核心思路
欧拉降幂 大指数取模题 先求 φ(m)\varphi(m),再处理指数
费马小定理 素数模数题 素数 ppφ(p)=p1\varphi(p)=p-1

经典例题

1. luogu-P2303

单个数欧拉函数模板题。分解 nn 的不同质因子,每遇到一个质因子就执行 ans = ans / p * (p - 1)

2. luogu-P2158

统计互质点对。核心是把每个分母对应的合法分子数量转化为欧拉函数值。

3. 欧拉降幂类题

当题目要求计算超大指数的 abmodma^b\bmod m,并且可以保证 gcd(a,m)=1\gcd(a,m)=1 时,欧拉定理给出指数周期 φ(m)\varphi(m)

参考

  • 欧拉函数公式
  • 欧拉定理