数论专题-欧拉函数
本篇博客是【数论专题】系列的第 \(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] 互质的情况
}
}

浙公网安备 33010602011771号