题解 SP4141 【ETF - Euler Totient Function】

实际发表时间:2020-04-15
https://www.luogu.com.cn/problem/SP4141

众所周知,欧拉函数\(φ(n)\)表示\(n\)以内与\(n\)互质的个数,所以把与\(n\)不互质的数筛掉即可

做法:

Step1:

把最后要返回的值\(res\)初始化为\(n\),以便后面筛的过程

Step2:

从2枚举到\(\sqrt{n}\),即枚举\(n\)质因数,如果\(n\%i=0\),那么就\(res= res\times \dfrac{i-1}{i}\),筛掉\(i\)的倍数,然后\(n/=i\)直到\(n\%i\not=0\),来保证以后再也不会筛到\(i\)的倍数
\(\mathcal{Q}:\)那怎么保证\(i\)是质因数呢?
\(\mathcal{A}:\)因为我们已经\(n/=i\)直到\(n\%i\not=0\),\(i\)的倍数(即非质因数)不会再能去筛

Step3:

筛完后,\(n\not=1\)怎么办?
那么这时候说明\(n\)就是一个质数,或者剩下的\(n\)是个大于\(\sqrt{n}\)的质因数,因为前面没被筛掉。所以我们重复原来的操作,\(res=res \times \dfrac{n-1}{n}\)即可
\(\mathcal{Q}:\)那怎么证明最多只有一个大于\(\sqrt{n}\)质因数呢?
\(\mathcal{A}:\)反证法,如果有两个大于\(\sqrt{n}\)的质因数,那它们乘起来就会大于\(n\)

代码:

inline int phi(int n)
{
	int res=n;//Step1
	for(int i=2; i*i<=n; ++i)//Step2
	{
		if(n%i) continue;
		res = res/i*(i-1);
		while(!(n%i)) n /= i;
	}
	if(n>1) res = res/n*(n-1);//Step3
	return res;
}
posted @ 2020-08-29 10:25  ADay526  阅读(192)  评论(0)    收藏  举报