[算法複習] 素數判定:歐拉篩 Miller_Rabin

摘取了以前的筆記並做了一些補充說明

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爲偶數爲止。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章