在做題中會經常遇到有關素數的問題,整理一下學過的兩種素數篩法。
時間複雜度:o(nloglogn)
我們知道乙個素數的倍數肯定是乙個合數,乙個合數可以由多個素數相乘得到,所以可以從2開始把2的倍數篩一遍,找到下個素數在篩一遍。篩完後素數的倍數都被篩掉了,剩下的就是素數。
**如下:
const
int n =
1e5;
int prime[n]
;bool vis[n]
;int
prime
(int n)}}
return cnt;
}
但我們可以發現30 =2 *15,30 =5 *6在後續的篩選過程中會重複篩除前面已經篩選過的,因此引入了尤拉篩。
每個數都有乙個最小素因數,利用這個因數去篩除每乙個合數。
時間複雜度o(n)
const
int n =
3e5;
bool vis[n]
;int prime[n]
;int
prime
(int n)
}return cnt;
}
素數之埃氏篩法 尤拉篩法
判斷數n是否為乙個素數,基本方法為從2開始向後列舉,若n不能被2,3,4,n 1整除,則n為素數,該判斷方法的時間複雜度為o n o n o n 更快的方法為,當列舉至n sqrt n n 時即可判斷是否為素數,該判斷方法的時間複雜度為o n o sqrt n o n 如下 寫法1,其中sqrt函式...
埃氏篩 尤拉篩
對於1 n範圍內素數的查詢,我們常用的二重迴圈暴力演算法的複雜度是o n2 如果利用開根縮小範圍的時間複雜度也無非是在o n nn sqrt n nn 而,這些演算法對於n在105以內都是可以接受的,但是如果需要更大範圍的素數表,這些演算法將顯得力不從心。下面將介紹更加高效的演算法。埃氏篩也叫素數篩...
線性篩法求素數(埃氏篩法 尤拉篩法)
篩法都是初始化把所有數都先設為素數,然後篩除合數。理解起來比較簡單,就是從小到大的列舉每乙個數,標記它的所有倍數都是合數 非素數 放到u i 為false,u中的下標對應的就是這個數的值。bool u maxn int num,su maxn 1.埃氏篩法 void prime 從小到大的篩選素數,...