尤拉篩(或者說是線性篩)的核心詳解

2021-10-11 08:48:25 字數 2077 閱讀 5054

首先尤拉篩的**

n=

16data=

[i for i in

range(0

,n)]

flag=[1

]*nsingle=

for i in

range(2

,n):

if flag[i]==1

:)for ii in

range

(len

(single)):

if single[ii]

*iflag[single[ii]

*i]=

0if i%single[ii]==0

:break

print

(data)

print

(flag)

print

(single)

假如去掉了if i%single[ii]==0:break

n=

16data=

[i for i in

range(0

,n)]

flag=[1

]*nsingle=

for i in

range(2

,n):

if flag[i]==1

:)for ii in

range

(len

(single)):

if single[ii]

*iflag[single[ii]

*i]=

0print

(data)

print

(flag)

print

(single)

這個就變成了乙個優化的埃氏篩:跟以下的優化方法一樣

n=

10a=

[i for i in

range(2

,n)]

for x in

range(2

,int

(n**

(0.5)+

1)):

m=xwhile m*x<=

(n-1):

try:

a.remove(m*x)

except

:pass

m+=1print

(a)

開始前我們首先要承認:

加上if i%single[ii]==0:break

尤拉篩的思想是只讓合數去最小質數那裡報到。

①如何讓合數只在最小的質數那裡報到呢,

那就是讓合數只能在最小質數和某個數乘積處被標記,在比最小質數大的質數處跳過;

對於數i,

我們從小到大遍歷質數列表single,

將質數跟i相乘得到合數,

對於任意的i,此時比質數列表的任意數大,

當i不能被質數列表從小到大檢索的較小的質數整除時,該較小的質數便是該質數乘i得到的合數的最小質數。

當遍歷到較大的質數時,發現i能整除single[ii]這個數,注意啊,此時該較大質數還是該質數乘i得到的合數的最小質數,只是該合數中的該最小質數出現了多個。

所以該合數還是出自最小質數,

因此if i%single[ii]==0:break放在該情況的合數也被標記完才跳,

對於x>ii時的所有質數和i的積single[x]*i,因為這些往後的所有得到的的積本身的最小質數是single[ii],因為single[x]>single[ii]且i的最小質數是single[ii],得出來的合數不符合①,所以直接跳出。要問這些積在什麼時候能被標記,答:也在積的最小質數single[ii]處被標記,那的等到數new_i=single[x]*old_i/single[ii],我相信這個new_i是指新的數,那個old_i就是指現在這個i的值,等到時候就是新的i乘最小質數也就是

(single[x]*old_i/single[ii])* single[ii] = single[x]*old_i。

over.

線性篩(尤拉篩)

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

尤拉篩 線性篩

實現 include using namespace std const int max n 1e8 int prime max n cnt bool st max n 使用bool陣列節省空間 void is prime int n intmain 每個合數只被自己最小的質因子篩去。現在證明在i ...

尤拉篩(線性篩)

尤拉篩多用於篩素數,時間複雜度是o n 主要原理 合數 最小質因子 合數 質數 這個合數的組成是唯一的,尤拉篩裡面只在這種情況篩一次,也就是每個數就篩一次,可以完成o n 的複雜度。每當列舉到乙個數,把這個數當作後面的那個數,在已經得到的質數里列舉當作最小質因子,看看這樣的組合能找到哪個合數,但是要...