埃氏篩 線性 尤拉 篩

2021-08-21 19:07:08 字數 1203 閱讀 9202

埃氏篩

簡單,暴力。

int isprime[50000];

void getlist(int size)

看似簡單,但不真搞明白這個,無法學會線性 ( 尤拉 ) 篩。

關鍵在於如何去做的合數,用了兩個引數,乙個是質數,即 prime[ i ] ,另乙個是質數的倍數,即 j 。相乘得到合數。

線性篩

埃氏篩的改良版,使乙個合數只被做出來一次。

模擬dfs的一些判重,用一定的順序( 如從小到大 )來去重。在這裡,我們便是保證每個合數只被最小的質因數做出來。

為什麼呢?

引用一段標準解釋:

prime 陣列中的素數是遞增的,當i能整除 prime[ j ],那麼 i*prime[ j+1 ]這個合數肯定被 prime[ j ] 乘以某個數篩掉。

因為i中含有 prime[ j ] , prime[ j ] 比 prime[ j+1 ]小,即 i = k*prime[ j ]。

那麼 i * prime[ j+1 ] = (k*prime[ j ]) * prime[ j+1 ] = k』 * prime[ j ],接下去的素數同理。所以不用篩下去了。

因此,在滿足 i%prime[ j ] == 0這個條件之前以及第一次滿足改條件時, prime[ j ] 必定是 prime[ j ] * i 的最小因子。

請看下面乙個樣例,假設我們的倍數遍歷到了9,而去乘它的質數到了3。

遍歷的倍數     9

質數表 2  3  5  7

這時候我們就可以換下乙個倍數10了,為什麼呢?

假如我們繼續,用9*5得到45,請注意,因為3是9的因數,所以3也是45的因數,且必定是45的最小質因數。因為3是9的最小質因數,除非9乘的質因數小於3,否則45的最小質因數就是3。5在3的右邊,所以winner就是3了。那麼15就是造這個合數所需要的倍數,肯定大於9,會在後面遍歷到這個倍數。

所以在3*9後,我們可以換下乙個倍數10了。

我將 i ,j 對換,來匹配埃氏篩的意義。 

int isprime[50000], prime[10000], tot;

void getlist(int size)

} return;

}

還是得多去複習。

埃氏篩 尤拉篩

對於1 n範圍內素數的查詢,我們常用的二重迴圈暴力演算法的複雜度是o n2 如果利用開根縮小範圍的時間複雜度也無非是在o n nn sqrt n nn 而,這些演算法對於n在105以內都是可以接受的,但是如果需要更大範圍的素數表,這些演算法將顯得力不從心。下面將介紹更加高效的演算法。埃氏篩也叫素數篩...

素數篩法 埃氏篩及尤拉篩

在做題中會經常遇到有關素數的問題,整理一下學過的兩種素數篩法。時間複雜度 o nloglogn 我們知道乙個素數的倍數肯定是乙個合數,乙個合數可以由多個素數相乘得到,所以可以從2開始把2的倍數篩一遍,找到下個素數在篩一遍。篩完後素數的倍數都被篩掉了,剩下的就是素數。如下 const int n 1e...

線性篩法求素數(埃氏篩法 尤拉篩法)

篩法都是初始化把所有數都先設為素數,然後篩除合數。理解起來比較簡單,就是從小到大的列舉每乙個數,標記它的所有倍數都是合數 非素數 放到u i 為false,u中的下標對應的就是這個數的值。bool u maxn int num,su maxn 1.埃氏篩法 void prime 從小到大的篩選素數,...