之前筆試寫到了乙個素數判斷,但是超時了(尷尬,當時知道用尤拉篩,但是忘記怎麼寫了),於是決定寫一篇部落格加深下印象 。
絕對不是水部落格
//判斷乙個數是不是素數
//當然可以用陣列來存狀態
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必定大於...