go 交叉編譯跨平臺
阿新 • • 發佈:2020-09-10
尤拉函式
尤拉函式 \(\varphi(a)\) 為小於等於 \(a\) 的正整數中與 \(a\) 互質的個數。
顯然得到 \(\varphi(1) = 1\) ,當 \(a\) 為質數的時候我們有 \(\varphi(a) = a-1\)
同時,我們有\(\varphi(n) = n\times(\frac{p-1}{p}) = p^{k-1}\times(p-1)\) ,其中 \(n = p^k\) 並且 \(p\) 為質數。
同時我們知道尤拉函式是一個積性函式,也就是當 \(\gcd(a,b) = 1\) 時有
\[\varphi(a\times b) = \varphi(a) \times \varphi(b) \]
我們可以將 \(n\) 唯一質因數分解, \(n = \prod_{i=1}^sp_i^{k_i}\) ,其中 \(p_i\) 表示第 \(i\) 個質因數, \(k_i\) 表示對應的質因數的因數個數 。
顯然我們得到了
\[\varphi(n) = n\times\prod_{i=1}^s\frac{p_i-1}{p_i} \]
如果我們找到 \(n\) 的最小質因數 \(p\) , 如果 \(\gcd(p,\frac{n}{p}) = 1\) ,那麼就有 \(\varphi(n) = \varphi(\frac{n}{p})\times\frac{p-1}{p}\)
如果 \(\gcd(p,\frac{n}{p}) = p\)
我們可以使用尤拉篩來線性求出尤拉函式
void init() { phi[1] = 1; for(int i = 2;i <= 100000;i ++){ if(!vis[i]) pri[++cnt] = i,phi[i] = i-1; for(int j = 1;j <= cnt&&(i*pri[j]<=100000);j ++){ vis[i*pri[j]] = 1; phi[i*pri[j]] = phi[i]*(pri[j]-1); if(i%pri[j]==0){ phi[i*pri[j]] = phi[i]*pri[j]; break; } } } }