数论专题-欧拉函数

本篇博客是【数论专题】系列的第 \(10\) 篇,希望大家多多支持。

欧拉函数 \(\varphi(n)\) 表示 \(1\sim n\) 中与 \(n\) 互质的数的个数,特别的,\(\varphi(1) = 1\)

欧拉函数是一个积性函数,若 \(n\perp m\),则 \(\varphi(n\times m) = \varphi(n)\times \varphi(m)\)

\(n\) 分解质因数后为 \(\prod_{i = 1}^mp_i^{q_i}\),则 \(\varphi(n) = n\times \prod_{i = 1}^m (1 - \frac{1}{p_i})\)

证明

  • 由于欧拉函数是一个积性函数,只需要考虑 \(p_i^{q_i}\) 的取值就能计算所有数的欧拉函数了。

  • 若一个数与 \(p_i^{q_i}\) 不互质,则这个数一定是 \(p_i\) 的倍数,那么 \(1\sim p_i^{q_i}\) 中有 \(p_i^{q_i - 1}\) 个数和 \(p_i^{q_i}\) 不互质,反过来和 \(p_i^{q_i}\) 互质的数的个数为 \(p_i^{q_i} - p_i^{q_i - 1} = p_i^{q_i}\times (1 - \frac{1}{p_i})\),则 \(\varphi(n) = n\times \prod_{i = 1}^m (1 - \frac{1}{p_i})\)

\(O(\sqrt n)\) 求解 \(\varphi(n)\)

phi = n;//phi 表示 phi(n)
for(int i = 2;i * i <= n;i ++)
    if(n % i == 0)
    {
        phi = phi / i * (i - 1);//乘上 (1 - 1 / p)
        while(n % i == 0) n /= i;//把 n 中的 i 全部筛去
    }
if(n != 1) phi = phi / n * (n - 1);

但是,以上算法如果计算多个数的欧拉函数,容易超时,需要使用欧拉筛优化,时间复杂度 \(O(n)\)

phi[i] = 1;
for(int i = 2;i <= n;i ++)
{
	if(phi[i] == 0)
		p[++ tot] = i, phi[i] = i - 1;//若 i 是质数,则 phi(i) = i - 1
	for(int j = 1;j <= tot && i * p[j] <= n;j ++)
	{
		if(i % p[j] == 0)//i 与 p[j] 不互质的情况
		{
			phi[i * p[j]] = phi[i] * p[j];
			break;
		}
		else phi[i * p[j]] = phi[i] * (p[j] - 1);//i 与 p[j] 互质的情况
	}
}
posted @ 2025-08-19 11:30  Loyal_Soldier  阅读(31)  评论(0)    收藏  举报