數論 線性尤拉篩

2021-09-22 22:56:18 字數 1824 閱讀 2516

const

int maxn=

1e5+5;

bool vis[maxn]

;ll prime[maxn]

,cnt=0;

void

getprime

(ll maxn)

}}

通常我們會採用的較為暴力的方法是巢狀入2層迴圈,也就是第一層迴圈是為了依次服務於每乙個#include

#include

using namespace std;

intmain()

if(flag)

printf

("%d "

,i);

//如果標誌還是為1說明其還是素數我們把它列印下來

i++;}

return0;

}以上是libm大佬在matlab課上教我的一種very basic的方法。那天晚上結束後,我又想了乙個很奇葩的寫法,雖然**長度很長,但是對於新學的小菜b如我可以試試,複雜度是o(n3/2)

#include

#include

using namespace std;

intmain()

return0;

}int

judge

(int n)

}}

對於以上的方法我並不太推薦,又耗時又費力,其複雜度為o(n2)但是倘若閒的蛋疼或者獵奇創新,我倒是很支援試試。

——————————————步入正題—————————————————

以上的2種方法可見其複雜度之大,雖然易於理解,但是在acm中容易被tle(超時),所以為了簡化其複雜度,我們對於素數的提煉有了新的方法,叫做——「素篩法」。

從數論角度理解就是任何乙個合數都可以用幾個素數變換相加得到

for example:

20=23+23+22的平方

一言以蔽之就是把依次素數的n次積全部消掉

比較簡單易懂的素篩如下:

#include

using namespace std;

intmain()

prime[0]

=1; prime[1]

=1;for

(int i=

2;i}for

(int i=

0;i)return0;

}

不得不說這種方法非常強大,愚蠢的我理解了半天才理解透,不過這裡要提及一下的是bool型和int/long long型一樣其作用是 返回 true或false,實際在這個**中你改為int也無傷大雅可以進行。

#include

using namespace std;

const

int maxn=

1e5+5;

bool vis[maxn]

;int prime[maxn]

,cnt=0;

void

getprime

(int maxn)

}for

(int b=

0;bintmain()

這串**與上面那個**類似。

其區別其實不大,上面的那串**直接用i的值的輸出質數,i非質數則不輸出;下面那串**動用陣列,直接把質數的集合輸入到乙個新的陣列中,最後把這個陣列列印下來即可。

easy to know 其複雜度遠遠比暴力低的多所以值得學習

小白第一次寫部落格,漏洞很多是必然的所以希望各位能多提寶貴意見

另外對libm大佬和閆旭然大佬的幫助表示由衷感謝!

———2019/5/18夜 於西北大學

數論 線性素數篩(尤拉法)

任何合數都能表示成一系列素數的積。線性素數篩的主要思想是每個合數必有乙個最小素因子,每個合數僅被它的最小素因子篩去正好一次,所以為線性時間。比如說 12 只能被 2 篩掉,12 2 6,不能被3篩掉,12 3 4 中體現在 if i prime j 0 break prime陣列中的素數是遞增的,當...

線性篩(尤拉篩)

昨天的考試跪的一塌糊塗 第一題水過,第二題帶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 ...