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];
}
}
}