题解 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;
}

浙公网安备 33010602011771号