尤拉篩 細節分析 證明

2021-10-24 17:19:32 字數 2423 閱讀 6274

尤拉篩法是用線性時間求取給定範圍內的素數的個數,當然素數的值也是可以記錄的,適用於大範圍性的素數求取,如果只是判斷某乙個素數,尤拉篩就顯得大材小用了(費空間資源),這時候可以考慮miller-rabin 素數測試。

尤拉函式的時間複雜度趨於o(n)的,即使是1e8也不在話下

講解尤拉篩之前回顧一下埃拉託斯特尼篩法

埃拉託斯特尼篩法:原理就是先找出乙個素數然後把這個素數的倍數都標記為合數(乙個正整數的所有倍數一定是合數,除了1),在下一次遇到被標記的數時直接跳過。

例如:第一次遍歷遇到素數2,所以(4,6,8,10…)被標記為合數

第二次遍歷遇到素數3,所以(9,12,15…)被標記為合數

第三次遍歷遇到合數4,因為已經被2的倍數標記所以直接跳過。

然後按照上面方法一直遍歷到最後就篩選出了所有素數

**

#include

#include

#include

using

namespace std;

int prime[

1000000];

/*埃拉託斯特尼篩法*/

bool vis[

100000001];

//1表示訪問過,0表示沒有訪問過

intmain()

}}printf

("%d"

,prime[0]

);return0;

}

注意:上面是我對埃拉託斯特尼篩法做了一定修改,便於後面理解尤拉篩。(望dalao勿吐槽)

但是埃拉託斯特尼篩法的時間複雜度o(nlognlogn)顯然對於1e8的資料是會超時的,其實篩選的過程中做了重複的操作,比如12這個數是2的倍數,也是3的倍數,就被2和3的倍數標記了兩次,後面較大的數被重複標記的次數更多,為了解決重複標記的問題,於是尤拉篩排上用場了。

先上**,方便講解

#include

#include

using

namespace std;

const

int maxn=

1e8+1;

const

int inf=

1e6;

int prime[

100000];

//存素數

bool vis[

100000001];

//0代表沒有訪問過,1訪問過

intmain()

for(

int j=

1;j<=prime[0]

&&i*prime[j]

<=n;j++

)//以i為倍數進行篩除,對所有已知素數的倍數(也就是合數)

}printf

("%d"

,prime[0]

);return0;

}

首先解釋為什麼要j從1開始並且j<=prime[0]

原因:因為我們要對每乙個已求出來的素數的倍數標記為合數,倍數為i,因為i會一直從2到n。

說到這裡有人會問,怎麼確定它就能保證不重複標記合數

這就是我們這裡if(i%prime[j]==0) break;的作用,如果不退出迴圈當我們繼續遍歷到i*prime[j+1]的時候,因為i%prime[j]=0,故i=t倍prime[j],所以i*prime[j+1]=t * prime[j] * prime[j+1],相當於是prime[j]的倍數(已經被標記過),所以這樣就會造成重複標記,因此我們跳出迴圈。

不會重複標記我們已經證明了

接下來有乙個很頭痛的事情就是你怎麼知道不會遺漏標記呢?(我也是想了很久,才明白,本蒟蒻太痛苦了)

舉個例子:在遍歷標記合數是prime[3]也就是5是從==i=5(5的5倍開始)==開始標記的(prim[j]的倍數標記始終是從i=prime[j]開始的,也就是i>=prime[j]),那麼5的四倍,三倍,兩倍不就沒有標記到嗎?

(其實一點就通)分析:我們知道任何乙個正整數都是可以由若干個素數的冪次的乘積構成(質因數分解),所以如果i其他更小的素數的倍數,所以已經被標記,故我們不需要再次標記,所以這樣就能夠解釋上面素數5的例子了。

趁熱打一下鐵吧

洛谷 p3912 素數個數

如果有分析不對的地方,還望dalao指出

尤拉函式尤拉篩

尤拉函式求小於等於n與n互質的數的個數 複習時發現這個知識點竟然沒有整理 n為素數即為n 1 除了其本身 n為素數的倍數 ola sushu j i ola i sushu j else ola sushu j i ola i sushu j 1 include include include in...

線性篩求尤拉函式的證明

若 i 為質數,則 varphi i i 1 若 p j mid i 則 varphi i times p j varphi i times p j 若 p i nmid i 則 varphi i times p j varphi i times varphi j varphi i times p ...

線性篩(尤拉篩)

昨天的考試跪的一塌糊塗 第一題水過,第二題帶wa的樸素,最後題忘了特判左端點全跪,分數比起預計得分整整打了個對折啊!步入正題 線性篩 尤拉篩 一般的篩法 ppt裡叫埃拉託斯特尼篩法,名字異常高貴 的效率是o nlglgn 其實很接近o n 啊!對於一些例如n 10000000的殘暴資料會跪,於是,線...