尤拉篩選法求素數 (例 洛谷P3912 素數個數)

2021-10-25 02:37:09 字數 1322 閱讀 9033

之前筆試寫到了乙個素數判斷,但是超時了(尷尬,當時知道用尤拉篩,但是忘記怎麼寫了),於是決定寫一篇部落格加深下印象 。

絕對不是水部落格

//判斷乙個數是不是素數

//當然可以用陣列來存狀態

boolf(

int n)

return

true

;}

那如果我們用陣列的下標來存狀態判斷是不是素數呢?

我們將素數從2開始挨個乘積的下標標記為非素數

int t[

10000]=

;voidf1(

int n)

}}

這樣t[i]=0的 i 就是素數。但是這樣很容易發現乙個缺點,就是會重複曬出一些數。比如12會被26、34、43、62重複篩選,這個時候就輪到尤拉篩選出場了,時間複雜度o(n)。

題目傳送門:p3912素數個數

題目大概意思:

求 1,2,⋯,n 中素數的個數。

對於 100% 的資料,1思路:

尤拉篩選法求素數,通過質數來篩掉他的倍數

關鍵:每個數都被他的最小質因數篩掉

這樣就可以避免重複篩選

5800000//10^8的範圍大概有5700000多個素數

要用bool型別的陣列判斷,不然會超記憶體

#include

#include

#define ll long long

using

namespace std;

/*尤拉篩選法求素數

通過質數來篩掉他的倍數

關鍵:每個數都被他的最小質因數篩掉

5800000//10^8的範圍大概有5700000多個素數

*/const

int maxn =

100000000+5

;bool dp[maxn]

;//判斷下標是否為素數

//用int陣列會超記憶體

int prim[

5800000]=

;//記錄素數的值

ll cnt =0;

boolf(

int n)

return

true;}

intmain()

//用素數篩掉非素數

for(

int j =

0; j<=n; j++)}

} cout << cnt << endl;

return0;

}

用最小質因數來篩選掉非素數,比如12只能被2 * 6篩,而不是被3 * 4篩掉。這樣就可以避免重複篩除。

尤拉篩選素數(洛谷p1217)

int prime 60000005 bool tag 100000005 memset tag,0,sizeof tag int cnt 0 tag 0 tag 1 1 for int i 2 i prime儲存所有素數,用來列舉最小質因子 tag判斷數字是否為質數,0為質數。注意本題因為記憶體限...

洛谷 P3383 篩素數 尤拉篩素數模板

如題,給定乙個範圍n,你需要處理m個某數字是否為質數的詢問 每個數字均在範圍1 n內 輸入格式 第一行包含兩個正整數n m,分別表示查詢的範圍和查詢的個數。接下來m行每行包含乙個不小於1且不大於n的整數,即詢問概數是否為質數。輸出格式 輸出包含m行,每行為yes或no,即依次為每乙個詢問的結果。樣例...

根號法 埃氏法 尤拉篩選。三種方法求素數

先上開根號求素數 乙個數n的最小質因子,必定小於開根號n 數學表達 a b n,若a 開根號n,b必定 開根號n,所以只要求2 開根號n,即可判斷n是不是素數。反證法如果數n的最小質因子a大於開根號n,那數n的另乙個因子b,b和a構成一對n的約數 必定大於a,那麼也大於根號n,這時候,a b必定大於...