摘取了以前的筆記並做了一些補充說明
9,素數判定
O(n) + O(1): 線性篩.
又叫歐拉篩。
先考慮一種樸素的想法。
對於每一個數\(k\), 我們枚舉\(i\),將\(ik\)標記爲合數。
因爲每個數都可以分解成若干個素數的積,我們只需枚舉每個素數作爲\(k\)即可。
但是複雜度依然很高,我們考慮優化。
對於每個數,僅用它最小的質因數來篩它。
我們用一個數組存儲質數,枚舉\(i\)作爲它的倍數,並且每次都判斷一下如果\(i\)是素數,則將其加入素數數組。
然後我們從小到大枚舉\(pri[j]\)用其篩除\(i * pri[j]\).
特別的,如果\(!(i \ mod \ pri[j])\) 那麼我們篩完就break.
下面我們來證明這個算法的正確性和複雜度。
正確性:
接下來我們證,如果\(!(i \ mod \ pri[j])\),那麼對於後面的\(i \cdot pri[j+k]\)來說,用\(pri[j+k]\)來篩一定是不優的,也就是這個剪枝肯定不會導致漏篩。
因爲\(!(i \ mod \ pri[j])\)所以我們可以設\(i = t \cdot pri[j]\)
那麼\(i \cdot pri[j+k] = t \cdot pri[j] \cdot pri[j+k]\)
又知\(pri[j+k] > pri[j]\),也就是說,用\(pri[j+k]\)來篩,不如等到\(i = t \cdot pri[j+k]\)的時候用\(pri[j]\)來篩。
所以這個剪枝肯定是合法的。
複雜度:
那麼爲什麼每個數僅被最小的質因數篩除了呢?
接下來我們證,這個剪枝可以導致每個數僅被最小的質因數篩除.
\(pm[m]\)爲\(m\)的質因數個數,對於一個數\(m\)設\(m = \prod_{i = 1}^{pm[m]}p_i\),其中\(p\)序列爲升序排列,若\(m\)不是被\(p_1\)篩除了,我們假設這個數是\(p_t\)。
我們先考慮\(m\)質因數大於\(2\)個的情況:
那麼篩掉\(m\)時我們枚舉到的\(i = \prod_{i = 1}^{pm[m]}(p_i) / p_t = b \cdot p_1\),\(b\)爲某個不爲\(1\)正整數。
此時,\(i\)會在枚舉到\(p_1\)的時候停下,也就是篩完\(b \cdot p_1 \cdot p_1\)就不篩了,也就不會篩\(m = b \cdot p_1 \cdot p_t\)了。與假設矛盾。
再考慮\(m\)剛好有兩個質因數的情況,此時\(m = p_1 \cdot p_2\),那麼根據假設,\(m\)被\(p_2\)篩掉了。
也就是在\(i = p_1\)的時候\(m\)被篩了。
這顯然是不合法的,因爲此時\(p_2\)這個質數還沒被加入素數數組。
所以\(m\)只可能在\(i = p_2\)時被\(p_1\)篩掉。與假設矛盾。
綜上,假設情況是不可能的,\(m\)必然會被其最小質因數篩除.
又因爲在第二個循環中,每循環一次必篩除一個數,而每個數只會被篩走一次,因此第二個循環的總次數爲被篩除的素數個數。所以複雜度是\(O(n)\)
O(\(\sqrt{n}\)): 暴力枚舉\(\sqrt{n}\)以內的因子
Miller_Rabin算法:
根據費馬小定理有\(a^{p - 1} \equiv 1 (mod \quad p)\),要求p是質數.
那麼如果對於等式\(a^{p - 1} \equiv 1 (mod \quad p)\),枚舉多個a,均滿足等式,那麼可以認爲當前的p有很大概率是素數。
但是依然有很大概率不是,,,因此這個時候採取二次探測來減小錯誤概率。
首先有定理:若\(a^2 \equiv 1 (mod \quad p)\)且p爲質數,那麼a = 1 或 p - 1.
證明如下:若等式成立,則\(a^{2} - 1 \equiv 0 (mod \quad p)\).
即\((a + 1)(a - 1) \equiv 0 (mod \quad p)\).
因此要麼\(a + 1 = p\) ---> \(a = p - 1\).
或者\(a - 1 = 0\) ---> \(a = 1\).
因爲這個探測是在滿足費馬測試的情況下才進行的,因此對於某個已經被枚舉過的a,我們已經有\(a^{p - 1} \equiv 1 (mod \quad p)\).我們設當前指數\(x = p - 1\)
當p不爲2且爲素數時,\(p\)一定爲奇數,即\(p - 1\)一定爲偶數.
因此我們可以把原式看做\(a^{\frac{x}{2}} \cdot a^{\frac{x}{2}} \equiv 1 (mod \quad p)\),其中可以設\(t = a^{\frac{x}{2}}\)。
那麼原式就是\(t \cdot t \equiv 1(mod \quad p)\)
那麼因爲這個是直接根據原式化過來的,因此我們已經有它同餘1了,因此只需要再判斷t是否等於1 或 p - 1即可。
如果t = 1 且 x爲偶數,那麼我們就又得到了一個新的式子\(a^{\frac{x}{2}} \equiv 1 (mod \quad p)\)
此時因爲x爲偶數,所以我們依然這個把這個新式子當做上面的式子重新做探測,直到不滿足t = 1且x爲偶數爲止。