\(\texttt{godmoo}\text{ }\text{の}\text{ }\texttt{數論學習筆記 之}\text{ }\boxed{質數}\)
定義
素數,又名質數,指的是在全體正整數中,僅能被 \(1\) 和它本身整除的數。
注意: 整除的概念是對整數而言的,但素數的研究僅針對與正整數。
性質
- 質數的分佈:一般情況下,我們記 \(\pi(n)\) 為 \([1,n]\) 中的質數的個數。黎曼給出了一個非常精確的計算公式,但是在 \(OI\) 中,我們暫且使用一下的公式:
- 偶質數:\(2\) 是唯一的偶指數。
判定
這裡的判定指的是對於單個數的判定。
- 試除法
根據質數的定義,我們只要逐一判斷是否能被 \([2,n-1]\) 中的整除即可。
又想到如果能被大於 \(\sqrt{n}\) 的數 \(k\) 整除,那麼必能被小於 \(\sqrt{n}\) 的 \(\frac{n}{k}\) 整除,所以只需判斷 \([2,\sqrt{n}]\) 即可。
時間複雜度 \(O(\sqrt{n})\)。
bool isprime(int n){
for(int i=2;i*i<=n;i++){
if(n%i==0) return false;
}
return true;
}
最佳化:可以判斷一下 \(n\) 模 \(6\) 的值,顯然當 \(n\) 不為 \(2\) 或 \(3\) 時,只有餘數為 \(1\) 或 \(5\) 時才有可能是質數,此時不需判斷是否會被 \(2\)、\(3\) 和 \(4\) 整除,記得特判 \(2\) 和 \(3\)。
bool isprime(int n){
if(n==2||n==3) return true;
if(n%6!=1&&n%6!=5) return false;
for(int i=5;i*i<=n;i++){
if(n%i==0) return false;
}
return true;
}
- \(\bm{Miller}\text{-}\bm{Rabin}\) 判斷法(待補)
篩法
篩法解決的是找出 \([2,n]\) 內所有的質數,如果對於每個數單個判斷,時間複雜度 \(O(n\sqrt{n})\),顯然不可接受。
- 埃氏篩 \(Eratosthenes\)
我們可以從試除法的最佳化中找到一些靈感:我們從質因子的角度出發,將 \([1,n]\) 中它的倍數全部標記掉,那麼最後剩下的數就是質數。
舉個例子,當 \(n=10\) 時:
\(2\) 並沒有被標記,所以它是質數,標記它的倍數 \(4\)、\(6\)、\(8\)、\(10\)。
\(3\) 並沒有被標記,所以它是質數,標記它的倍數 \(6\)、\(9\)。
\(5\) 並沒有被標記,所以它是質數,標記它的倍數 \(10\)。
\(7\) 並沒有被標記,所以它是質數,沒有剩下的數可以給它標記。
所以質數有 \(2\)、\(3\)、\(5\)、\(7\)。
這樣我們就找出了所有的質數。
那這個演算法的時間複雜度是多少呢?我們發現這個演算法的時間複雜度實際為\(O(\sum{\frac{n}{p}})\),也就是我們需要求出 \(O(\sum\frac{1}{p})\),這個東西是等於 \(O(loglogn)\) 的,於是複雜度為 \(O(nloglogn)\)。證明我不會。
[程式碼應該很好寫]
- 尤拉篩/線性篩
儘管埃氏篩的複雜度已經非常優秀了,但是遇到 \(luogu\) 的毒瘤題目還是招架不住,我們先來分析它的缺陷。
舉個例子,當 \(n=10\) 時:
\(2\) 並沒有被標記,所以它是質數,標記它的倍數 \(4\)、\(6\)、\(8\)、\(10\)。
\(3\) 並沒有被標記,所以它是質數,標記它的倍數 \(6\)、\(9\)。
\(5\) 並沒有被標記,所以它是質數,標記它的倍數 \(10\)。
\(7\) 並沒有被標記,所以它是質數,沒有剩下的數可以給它標記。
所以質數有 \(2\)、\(3\)、\(5\)、\(7\)。
我們發現,\(6\) 被篩到了兩次,被 \(2\) 和 \(3\) 篩到了。如果我們想追求線性複雜度,那麼就要使每個數剛好被篩到一次,這就是線性篩的思路。
容易想到,使用每個數的最小質因子將它篩掉,但是直接這麼做並不好維護,我們不如反過來,使用最大真因數篩掉他。我們可以發現:
所以其實本質是一樣的。
void euler(){
vis[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]) pr[++cnt]=i;
// 對於每個數與質數表中的數相乘
for(int j=1;j<=cnt&&i*pr[j]<=n;j++){
vis[i*pr[j]]=1; // 可以乘出來的都是合數
if(i%pr[j]==0) break; // 再往後枚,質數表中的就不是最小質因子了
}
}
}