首先尤拉篩的**
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:breakover.尤拉篩的思想是只讓合數去最小質數那裡報到。
①如何讓合數只在最小的質數那裡報到呢,
那就是讓合數只能在最小質數和某個數乘積處被標記,在比最小質數大的質數處跳過;
對於數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。
線性篩(尤拉篩)
昨天的考試跪的一塌糊塗 第一題水過,第二題帶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 的複雜度。每當列舉到乙個數,把這個數當作後面的那個數,在已經得到的質數里列舉當作最小質因子,看看這樣的組合能找到哪個合數,但是要...