素數線性篩

2021-07-24 08:05:11 字數 1286 閱讀 2353

ps:證明**神牛部落格。

#include

#include

using

namespace

std;

const

int n=100100;

int v[n],p[n],n,m,tot;

int main()

}

}

首先,先明確乙個條件,任何合數都能表示成一系列素數的積。

不管 i 是否是素數,都會執行到「關鍵處1」,

①如果 i 都是是素數的話,那簡單,乙個大的素數 i 乘以不大於 i 的素數,這樣篩除的數跟之前的是不會重複的。篩出的數都是 n=p1*p2的形式, p1,p2之間不相等

②如果 i 是合數,此時 i 可以表示成遞增素數相乘 i=

p1∗p

2∗..

.∗pn

p_i都是素數(2

≤i≤n

),pi

≤pj(

i≤j)

p1 是最小的係數。

根據「關鍵處2」的定義,當p1

==pri

me[j

] 的時候,篩除就終止了,也就是說,只能篩出不大於p1

的質數*i。

我們可以直觀地舉個例子。i=2*3*5

此時能篩除 2*i ,不能篩除 3*i

如果能篩除3*i 的話,當 i』 等於 i』=3*3*5 時,篩除2*i』 就和前面重複了。

需要證明的東西:

乙個數會不會被重複篩除。

合數肯定會被乾掉。

根據上面」只能篩出不大於p1的質數*i」的條件,現在分析乙個數會不會被重複篩除。

設這個數為 x=p1*p2*…*pn, pi都是素數(1<=i<=n) , pi<=pj ( i<=j )

當 i = 2 時,就是上面①的情況,

當 i >2 時, 就是上面②的情況, 對於 i ,第乙個能滿足篩除 x 的數 y 必然為 y=p2*p3…*pn(p2可以與p1相等或不等),而且滿足條件的 y 有且只有乙個。所以不會重複刪除。

證明合數肯定會被乾掉? 用歸納法吧。

模擬乙個模型,比如說我們要找出 n 中2個不同的數的所有組合 ,1<=i<=n, 1<=j<=n,

我們會這麼寫

for (i=1; i

i ) for (j=i+1; j

<=n; ++j)

我們取 j=i+1 便能保證組合不會重複。快速篩法大概也是這個道理,不過這裡比較難理解,沒那麼直觀。

素數篩法(素數篩 線性篩)

求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...

線性篩素數

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

線性素數篩

兩個星期之前,如果你讓我篩一下素數,我會告訴你很簡單,然後一頓敲 define size 1000000 int main int pos int flag for int i 2 i size i if flag 1 printf 2f double clock clocks per sec re...