常用的篩素數的算有兩種:
1). eratosthenes篩法:把[1,n]素數p的倍數篩出去,剩餘的就是素數。
[cpp]
int prime[n], np;
bool vis[n];
void get_prime()
} }
演算法複雜度o(n*log log n)
2). 線線篩法:eratosthenes篩法會有很多重複的篩選,此演算法是對eratosthenes篩法的改進.
線性篩素數的基本思想是:每個合數只被篩一次,將被其最大因數篩掉。
假設我們依據flag陣列從小到大判斷每個數是否是素數,如果當前該數還未被篩掉,那麼就是素數,因為在比它小的數中沒有發現因數,將素數加入素數表中。對每乙個數i(不論素數或合數),用它篩掉flag陣列中以它為最大因數的數。因為每個數隻去篩以它為最大因數的數,所以每個合數只會被乙個數篩,就是它的最大因數,以此達到線性的複雜度。www.2cto.com
假設當前的數是i。以i為最大因數的數是哪些呢?這些數必然是i乘上乙個比它小的素數(如果該數是i乘上乙個比它大的素數,顯然i不會是該數的最大因數;如果是i乘上乙個合數x = p1*p2*...*pk (pi為素數),顯然通過將x的一些素因數與i相乘會得到比i大的因數)。
假設i可以表示為素數乘積:i = p1*p2*...*pn,x是乙個比i小的素數(x顯然已經被篩出來了,在我們的素數表中),其中i最小的素因數是p1。i只有與當前素數表中p<=p1的素數相乘,得到的數y才以i為最大因數。反證:如果i乘上pm得到y = i*pm,且pm>p1,那麼y有因數y/p1 > i = y/pm。
所以對每乙個數i,乘上素數表中不大於i的最小素因數p1的素數,將得到的數從flag陣列中篩去,我們就可以**性的時間複雜度下得到乙個素數表。
[cpp]
int prime[n], np;
bool vis[n];
void get_prime2()
} } 在該演算法中,每個合數都只被最小的素數篩去,演算法複雜度o(n)
素數篩法(素數篩 線性篩)
求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...
素數判定,素數篩
這些零碎的知識點每個都學過n次了,但隔一段時間就會忘,記錄下來 素數定義 只能被自身和1整除的大於1的正整數 通過這個定義,我們就可以得出判斷素數的 這裡用到了cmath中的sqrt函式,其原型為double sqrt double 所以在取上界的時候,為了避免double帶來的精度丟失,寧可多列舉...
素數與素數篩
素數篩法 線性篩法 啊,耳熟能詳。素數又稱質數,乙個大於1 11的自然數,除了1 11和它本身外,不能被其他自然數整除,換句話說就是該數除了1 11和它本身以外不再有其他的因數 否則稱為合數。啊!1 11不是素數啊 啊,也耳熟能詳了,暴力列舉一下除1 11和本身的自然數是否會被整除。bool is ...