专栏文章

学习笔记:求解欧拉函数

算法·理论参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mio4s6k1
此快照首次捕获于
2025/12/02 13:21
3 个月前
此快照最后确认于
2025/12/02 13:21
3 个月前
查看原文

什么是欧拉函数?

φ(n)\varphi(n) 表示小于等于 nn 的正整数中,与 nn 互质的数的个数。记作:
φ(n)={1kngcd(k,n)=1}\varphi(n) = | \{ 1 \le k \le n | \gcd(k,n) = 1 \} |

如何求解?

1.若 nn 为质数:

φ(n)=n1\varphi(n) = n - 1

2.若 n=pkn = p^kpp为质数:

φ(pk)=pkpk1=pk(11p)\varphi(p^k) = p^k - p^{k - 1} = p^k \left( 1 - \frac{1}{p} \right)

3.若 n=a×b,gcd(a,b)=1n = a \times b,\gcd(a,b) = 1

φ(ab)=φ(a)φ(b)\varphi(ab) = \varphi(a)\varphi(b)

4.通项公式:

对于任意正整数 nn,其质因数分解为:
n=p1k1p2k2pmkmn = p_1^{k_1} p_2^{k_2} \cdots p_m^{k_m}
则:
φ(n)=n×(11p1)×(11p2)××(11pm)=ni=1m(11pi)\varphi(n) = n \times \left(1 - \frac{1}{p_1} \right) \times \left(1 - \frac{1}{p_2} \right) \times \cdots \times \left(1 - \frac{1}{p_m} \right) = n \prod_{i = 1}^m \left(1 - \frac{1}{p_i} \right)

关于代码实现

我们注意到通项公式中有一个分数:1pi\frac{1}{p_i}。在数论中,我们需要让所有数尽可能为整数。而在 C++\texttt{C++} 环境中,1pi\frac{1}{p_i} 这个分数在整数下一定为 00
所以,我们需要改造这个式子。换句话说,我们需要避免精度问题。
我们先将通项公式转化成伪代码语言:
CPP
res <- n 
for i = 2 to sqrt n:
    if (i 为质数且 i|n)
        res <- res * (1 - 1 / i);
重点就在这个式子:
resres(11 / i)res \gets res * (1 - 1 \ / \ i)
去括号,得:
resresres / ires \gets res - res \ / \ i
res / ires \ / \ i 提出来,得
resres / i×(i1)res \gets res \ / \ i \times (i - 1)
这个式子不会出现精度问题。
为什么 res / ires \ / \ i 不会出现精度问题呢?
因为 iinn 的质因子,那么必然有 iresi \mid res
这样代码就好写了。

评论

0 条评论,欢迎与作者交流。

正在加载评论...