欧拉函数
欧拉函数
文章转载自算法学习笔记(18): 欧拉函数 - 知乎 (zhihu.com),如有侵权,请联系作者删除。
欧拉函数的引入及性质
欧拉函数\(\varphi(x)\)是一个非常重要的函数,它定义为小于(或不大于,这里是一样的)\(x\)但与\(x\)互质的正整数的数量,例如\(\varphi (12)=4\),有1、5、7、11与之互质。特别地,规定\(\varphi (1)=1\)。
主要性质如下:
若\(p\)是质数,则\(\varphi (p^n)=p^{n-1}(p-1)\)
若\(a|x\),则\(\varphi (ax)=a\varphi (x)\)
若\(a、b\)互质,则\(\varphi(a)\varphi(b)=\varphi(ab)\)
(这里跳过证明,想要看证明的可以看看原文章:算法学习笔记(18): 欧拉函数 - 知乎 (zhihu.com))(也许我自己以后会补充?)
注意:符合第三个性质的函数称为积性函数。
我们把正整数质因数分解:
\(x={p_1}^{k_1}{p_2}^{k_2}······{p_n}^{k_n}\)。
所有\({p_i}^{k_i}\)两两互质,由欧拉函数的性质得:
\(\varphi (x)={p_1}^{k_1-1}(p_1-1){p_2}^{k_2-1}(p_2-1)······{p_n}^{k_n-1}(p_n-1)\).
即:
\(\varphi (x)=x·\frac{p_1-1}{p_1}·\frac{p_2-1}{p_2}······\frac{p_n-1}{p_n}\)
我们可以利用这个方法以最坏的时间复杂度\(O(\sqrt{n})\)内求出指定正整数的欧拉函数值。
int phi(int n) |
我们还可以把求欧拉函数与筛法结合起来,例如用类似埃氏筛的方法,求1~n的欧拉函数:
int phi[MAXN]; |
可以保证范围内每个数都能被它的所有质因数筛且只筛一次。注意一个正整数\(x\)是质数的充要条件是
\(\varphi (x)=x-1\),所以我们其实顺便求出了所有的素数。这个方法的时间复杂度是\(O(nloglog\ n)\),比一个一个求的\(O(n\sqrt{n})\)更好。
当然也可以在欧拉筛途中顺便求出:
void init(int n) |
这里没有进行质因数分解,综合运用了开头提到的三种性质,时间复杂度为\(O(n)\) 。