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 ...