尤拉篩法求素數

2021-08-09 15:41:56 字數 1069 閱讀 3673

尤拉篩法通過不篩除篩除過的數來將時間複雜度優化到

尤拉篩法求素數

首先,我們知道當乙個數為素數的時候,它的倍數肯定不是素數。所以我們可以從2開始通過乘積篩掉所有的合數。

將所有合數標記,保證不被重複篩除,時間複雜度為o(n)。**比較簡單↓_↓

/*求小於等於n的素數的個數*/

#include#includeusing namespace std;

int main()

{ int n, cnt = 0;

int prime[100001];//存素數

bool vis[100001];//保證不做素數的倍數

scanf("%d", &n);

memset(vis, false, sizeof(vis));//初始化

memset(prime, 0, sizeof(prime));

for(int i = 2; i <= n; i++)

{if(!vis[i])//不是目前找到的素數的倍數

prime[cnt++] = i;//找到素數~

for(int j = 0; j

if(i % prime[j] == 0) break;←_←這一步比較難理解

解釋:首先,任何合數都能表示成多個素數的積。所以,任何的合數肯定有乙個最小質因子。我們通過這個最小質因子就可以判斷什麼時候不用繼續篩下去了。

當i是prime[j]的整數倍時(i % prime[j] == 0),i*prime[j+1]肯定被篩過,跳出迴圈。

因為i可以看做prime[j]*某個數, i*prime[j+1]就可以看做 prime[j]*某個數*prime[j+1] 。而 prime[j] 必定小於 prime[j+1],

所以 i*prime[j+1] 必定已經被 prime[j]*某個數 篩掉,就不用再做了√

同時我們可以發現在滿足程式裡的兩個條件的時候,prime[j]必定是prime[j]*i的最小質因子。這個性質在某些題裡可以用到。

p.s.這裡初學鹹魚,如有錯誤歡迎各位大佬們指出~

尤拉篩法求素數

埃氏篩法確實大大提高了求素數的效率,但是會有很多合數被重複刪去,在資料大小超過1e8的時候會支撐不住。尤拉篩法便有效先看 解決了這個問題,將時間複雜度降低到了o n 先看 int ans 0,pri max n 尤拉篩法 bool vis max n void getpri vis i pri j ...

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

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

素數線性篩法(尤拉篩)

之前寫的埃式篩法複雜度達o n log n lo gn o n logn logn o n lo gn l ogn 在大數字的時候可能複雜度還不夠理想。這種做法對於乙個合數有可能會篩了多次,導致重複做功。引入尤拉篩法能夠解決這種多次篩同乙個數字的情況,理論演算法複雜度o n o n o n 精髓在於...