什么是欧拉函数?
φ(n) 表示小于等于
n 的正整数中,与
n 互质的数的个数。记作:
φ(n)=∣{1≤k≤n∣gcd(k,n)=1}∣
如何求解?
1.若 n 为质数:
φ(n)=n−1
2.若 n=pk,p为质数:
φ(pk)=pk−pk−1=pk(1−p1)
3.若 n=a×b,gcd(a,b)=1:
φ(ab)=φ(a)φ(b)
4.通项公式:
n=p1k1p2k2⋯pmkm
则:
φ(n)=n×(1−p11)×(1−p21)×⋯×(1−pm1)=ni=1∏m(1−pi1)
关于代码实现
我们注意到通项公式中有一个分数:
pi1。在数论中,我们需要让所有数尽可能为整数。而在
C++ 环境中,
pi1 这个分数在整数下一定为
0。
所以,我们需要改造这个式子。换句话说,我们需要避免精度问题。
我们先将通项公式转化成伪代码语言:
CPPres <- n
for i = 2 to sqrt n:
if (i 为质数且 i|n)
res <- res * (1 - 1 / i);
重点就在这个式子:
res←res∗(1−1 / i)
去括号,得:
res←res−res / i
将
res / i 提出来,得
res←res / i×(i−1)
这个式子不会出现精度问题。
为什么
res / i 不会出现精度问题呢?
因为
i 是
n 的质因子,那么必然有
i∣res。
这样代码就好写了。