尋找素數是我們剛學迴圈的時候就會遇到的乙個問題,但我們第一時間想到的便是暴力查詢.判斷乙個素數的複雜的就是o(n),通過迴圈中值判斷到根號n可以優化一些,不過複雜度也達不到預期.但在數論中,有更完美的方法,埃氏篩法o(nlog(logn)),尤拉篩法o(n).
思想:從2開始,將每個素數的倍數都標記成合數,用來達到篩選素數的目的.
下面給出**:
const
int maxn =
1000000
;int prime[maxn]
;void
prime()
}}}
而埃氏篩法有個缺陷,某些合數可能被篩選多次.然而尤拉篩法卻是優化了這個問題.
思想:保證每個合數只被這個合數的最小的質因子篩出,而且之篩一次,沒有重複篩除.
const
int maxn =
1000000
;bool prime[maxn]
;//保證不是素數的倍數
int tot, p[maxn]
;//tot是素數的個數,p用來存素數
void
prime()
}}
其中注釋為"關鍵的地方":
因為任何合數都能表示成多個素數的積.所以,每個合數都有乙個最小質因子.我們通過這個最小質因子就可以判斷什麼時候不用篩選下去了.
當i%p[j]==0, i是p[j]的倍數時,i * p[j+1]肯定被篩過,跳出迴圈.
因為i可以看做是p[j]* k(k是某個正整數),而i* p[j+1]就可以看作p[j]* k* p[j+1].而p[j]必定小於p[j+1],所以i* p[j+1]必定被p[j]* k篩掉,就不用繼續迴圈了.
尤拉篩法(線性篩素數)
以下內容 include include using namespace std intmain printf d n cnt return0 其中注釋為 關鍵!的句子的解釋大概如下 首先,任何合數都能表示成多個素數的積。所以,任何的合數肯定有乙個最小質因子。我們通過這個最小質因子就可以判斷什麼時候...
線性篩(尤拉篩)
昨天的考試跪的一塌糊塗 第一題水過,第二題帶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 ...