篩法求素數 線性篩法求素數

2021-08-14 20:05:58 字數 2316 閱讀 5794

2023年更新版:

篩法求素數&線性篩法求素數

要理解篩法求素數首先要知道乙個定理,

整數唯一分解定理:任意大於等於2的正整數都有且只有一種方式寫出其質因子的乘積表示式。

a =p1p2p3p4…pn(pi是素數且pi

<=pj)

eg:2=2

4=22

12=223

36=2233

也就是說任意乙個合數都能分成乙個素數和另乙個數(另乙個數可以是素數也可以是合數)的乘積

eg:4=22

12=26

15=3*5

即任意乙個合數都有乙個比它本身小的素因子。

這樣的話,如果要求1-n的所有素數,只要把1-n內所有素數的倍數刪掉,剩下的就都是素數了。

先看**:

普通篩法求素數

#include#include#includeusing namespace std;

#define ll long long

#define n 100

bool isprime[n];//1

int pri[n];//2

void prime()}}

return;

}

上邊**裡:

isprime陣列的作用是,判斷乙個數是否是素數,我們可以規定

if(isprime[i]==0)代表i是素數

else 代表i是合數

一開始把isprime陣列的值全部置0,假設1-n內所有數都是素數,然後把ispime[1]特判掉

2.pri陣列用來儲存已經確定的素數

3.乙個迴圈從2開始到sqrt(n)結束,迴圈內如果發現isprime[i]==0,那麼把i存到pri陣列內(即上面的4那一行),接著再來乙個迴圈把i這個素數的倍數全部刪掉(上面的5),這個迴圈從i*i開始,每次加i,到n結束,這樣就可以把i*i,i*(i+1),i*(i+2)…i*(i+k),把n以內i的倍數全部刪掉。

接著說1 .為什麼到sqrt(n)就可以結束了:

假設乙個小於n的合數 x=ab ,設 a<=b;

那麼a必定小於sqrt(n),也就是說這個合數必定有乙個小於 sqrt(n)的素因子,那麼這個數一定能在2-sqrt(n)內被某個數刪掉

2.為什麼從i *i開始而不是從2*i開始

假設乙個合數x=ij (j < i )

那麼這個數在遍歷 j 時就已經被刪掉了

然後看線性篩法

仔細分析上面的篩法其實是會造成重複篩合數,比如 12 在遍歷2的時候篩到2*6 篩掉一次,在遍歷3的時候篩到3*4 又篩了一次

快速篩法就解決了這個問題

先看**:

#include#include#includeusing namespace std;

#define ll long long

#define n 100

bool isprime[n];

int pri[n];

void prime2()

for(int j=1;j上邊**:

1。不管i是素數還是合數,都會執行到「1「這個地方。

這個迴圈的作用是

如果i是素數,會篩掉所有的i*k(其中k是所有小於等於i的素數)

看**j從1開始,到cnt-1結束,每次把i*pri[j]標記為合數,即是說把從pri[1]=2到pri[cnt-1],與i的乘積篩掉

eg:i=5 時,j從1開始,此時cnt等於3 ,即j到3結束,會把5*2,5*3,篩掉

如果i是合數,會篩掉所有的i*k(其中k是所有小於等於i的最小素因子的素數)

看**j從1開始,到cnt-1結束,每次把i*pri[j]標記為合數,然後「//2「這一行的作用就是在pri[j]等於i的最小素因子時跳出迴圈。因為pri[j]是從小到大列舉的,所以遇見的第乙個i%pri[j]==0就是i的最小素因子

現在證明這個篩法

不會造成重複篩

對於任意乙個 x =p1p2p3p4…pn(pi是素數且pi

<=pj)

這個x能且只能被y=p2p3p4…pn(pi是素數且pi

<=pj)篩掉。

eg:42=2*3*7,42只能被3*7=21篩掉。

可以把所有合數都篩掉

對於任意乙個 x =p1p2p3p4…pn(pi是素數且pi

<=pj)

這個數一定能被y=p2p3p4…pn(pi是素數且pi

<=pj)篩掉。

所以一定可以把所有合數都篩掉

線性篩法求素數

線性篩法求素數,顧名思義,其時間複雜度為o n 我是第一次接觸線性篩法求素數,其中有些難理解的地方的確花了很多時間。先放出 難點在於 為什麼這裡要break?先可以得出乙個結論,此時的prime j 為 i prime j 的最小質因數。現設x p1 a為合數,且p1為其最小的質因子,a為質數或合數...

素數篩法求素數

素數篩類似於打表標記,預先處理掉非素數的數,即素數的倍數 任意非素數都可以由幾個素數相乘得到 於是效率比暴力求解快得多。埃氏篩法的效率為o n loglog n 簡單易懂,但是會重複標記,比如當i為2時,6會被標記掉,然而當i為3時,6又會被重複標記,這樣的重複訪問加大了時間複雜度,於是有了尤拉篩。...

篩法求素數

素數篩法就是每次把已知的素數的倍數曬去,篩掉前sqrt n 中素數的倍數就可以了 先把n個自然數按次序排列起來。1不是質數,也不是合數,要划去。第二個數2是質數留下來,而把2後面所有能被2整除的數都劃去。2後面第乙個沒劃去的數是3,把3留下,再把3後面所有能被3整除的數都劃去。3後面第乙個沒劃去的數...