題解 SP4141 【ETF - Euler Totient Function】
阿新 • • 發佈:2020-08-29
實際發表時間: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}:\)
\(\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}\)
程式碼:
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;
}