總結 線性篩質數

2021-10-08 23:03:55 字數 2446 閱讀 3008

怎麼篩素數

直接列舉i:2

→n−1

i:2\rightarrow n-1

i:2→n−

1,如果i

ii是n

nn的因數,則n

nn一定是質數,如果找完都沒找到這樣的i

ii說明n

nn是合數,純粹是根據定義來判斷

bool

check

(int n)

return

true

;}

考慮到如果乙個數i

ii為n

nn的因數,則n

i\frac

in​一定也為n

nn的因數,所以列舉i

ii和列舉n

i\frac n i

in​是等價的,如圖,在5

55之前所有數都能找到與之對應的數,所以我們列舉到5

55即可,那麼5

55是怎麼來的呢?很明顯是n

\sqrt

n​吶,因為這種數對的臨界就是i

ii和i

ii(當i2=

ni^2=n

i2=n

時)

bool

check

(int n)

return

true

;}

但這些依然不夠,有時我們需要得出一整段數中的質數,當然可以用上面的方法對這些數乙個乙個的判斷,但這樣太慢了,這時就要用到素數篩

埃篩的核心思想是乙個合數一定是乙個質數的倍數(是個人都知道),所以我們只需列舉每乙個質數,然後用它的倍數篩掉合數,但是我們需要列舉質數,可是我們埃篩就是為了得到質數,那怎麼辦?

首先我們知道,當我們列舉到乙個數時,這個數要麼被篩過了,要麼還沒被篩,那麼沒篩的是否就是質數呢?答案是肯定的,因為根據質數的定義,「除了1和它自身外,不能被其他自然數整除的數叫做質數」,換句話講,乙個質數的因數只有1和他本身,所以他還沒被篩的話,就一定是質數了

void

get_prime

(int n)}}

}

剛才的篩法會重複篩掉一些,如質數2會篩6,而3也會篩6,這就慢了許多,那麼我們可不可以只篩一次呢,辦法是有的,但不告訴你,就是只篩這個合數的最小質因數

依次列舉每乙個數

若當前數沒被篩,則把這個數加入質數集合

對於每乙個數,列舉當前已知質數,並相應篩掉當前數

×列舉到

的質數當前數 \times 列舉到的質數

當前數×列舉

到的質數

,而被篩掉的那個數的最小質因數一定是列舉到的質數(為什麼看後面)

如果i

ii是列舉到的質數的倍數,停止列舉質數

先看**理解做法

bool isprime[maxn]

;int prime[maxn]

;int cnt=0;

void

get_prime

(int n)

for(

int j=

1;j<=cnt && i*prime[j]

<=n;j++)}

}//最終的prime就儲存了n以內的所有質數

if

(i%prime[j]==0

)break

;

這段程式保證了篩掉的那個數的最小質因數一定是prime[j]

理由:

第一條說明了:i

ii的最小質因數是pri

me[j

]prime[j]

prime[

j],那麼i×p

rime

[j]i×prime[j]

i×prim

e[j]

的最小質因數也是pri

me[j

]prime[j]

prime[

j]。所以,j

jj一定可以保證了篩掉的那個數的最小質因數是pri

me[j

]prime[j]

prime[

j]第二條說明了:如果到j後不break,那麼繼續篩下去會不用最小質因數篩數,是無用的

乙個作者進入過的誤區:

當i

ii還不大的時候,可能會一層內就篩去大量合數,看上去耗時比較大

但是,由於保證了篩去的合數日後將不會再被篩(總共只篩一次),複雜度是線性的。到i

ii接近 n

nn 時,你會發現每層幾乎都不用做什麼事。

最後,希望大家不要因為它快就忘記它原本的名字,它叫歐 拉 篩

質數線性篩法 O n

埃氏篩法o nloglogn 仍會重複標記合數 such as i 2時 12 2 6,先會被 2 標記已是合數 i 3時 12 3 4,又被標記了一次 我們在生成乙個需要標記的合數時,每次只向現有的數中乘上乙個質因子,並且讓它是所生成合數的最小質因子 code include include us...

演算法 線性篩質數

輸出從0 00到1000000 1000000 100000 0的所有質數。首先0 00和1 11不是質數,從2 22開始逐個判斷是否為質數。如果t tt為質數,那麼對於任意正整數k kk,k t k times t k t不是質數,因此可以將k t k times t k t篩去。如果t tt已經...

線性篩質數,線性求尤拉

本篇前半部分講線性篩質數,也叫尤拉篩,後半篇講解線性求尤拉函式。我們有一種篩質數的辦法,就是列舉每個質數,然後把這個質數的倍數都篩掉,這個做法比較簡單,在這裡不做過多介紹。尤拉篩就是在這個方法的基礎上,使得每個合數只會被它最小的那個質因子篩掉,保證了複雜度是線性的 memset isprime,1,...