篩法都是初始化把所有數都先設為素數,然後篩除合數。理解起來比較簡單,就是從小到大的列舉每乙個數,標記它的所有倍數都是合數(非素數)放到u[ i ]為false,u中的下標對應的就是這個數的值。
bool u[maxn]
;int num,su[maxn]
;// 1. 埃氏篩法
void prime (
)}
從小到大的篩選素數,事實上還是會有很多重複篩選的情況,所以尤拉篩選就出現了,每個合數只會被篩一遍。
其思想就是:每個合數只被它的最小質因子篩選一次。
void
findsu()
}}
解釋一下if(i%su[j]==0) break;
的意思:
因為任何合數都能表示成多個素數的積.所以,每個合數都有乙個最小質因子.我們通過這個最小質因子就可以判斷什麼時候不用篩選下去了.
當i % su[j]==0
, i是su[j]的倍數時,如果繼續迴圈,對於i * su[j+1]
這個數一定在後面還會被篩一次,為什麼呢?
因為這個時候i=su[j]* k(k是某個正整數)
,所以i * su[j+1] = su[j]* k* su[j+1]
.而su[j]
必定小於su[j+1]
,所以i* su[j+1]
必定被後面當i=su[j+1]* k
的時候再一次篩掉,所以我們break;
例如 :i = 8 ,j = 1,su[j] = 2,如果不跳出迴圈,su[j+1] = 3,8 * 3 = 2 * 4 * 3 = 2 * 12,在i = 12時會重複篩選一次。尤拉篩法的原理便是通過最小素因子來消除。
埃氏篩法是從小到大列舉每個數的倍數,而尤拉篩法從小到大是列舉每個素數的倍數。
素數之埃氏篩法 尤拉篩法
判斷數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函式...
素數篩法 埃氏篩及尤拉篩
在做題中會經常遇到有關素數的問題,整理一下學過的兩種素數篩法。時間複雜度 o nloglogn 我們知道乙個素數的倍數肯定是乙個合數,乙個合數可以由多個素數相乘得到,所以可以從2開始把2的倍數篩一遍,找到下個素數在篩一遍。篩完後素數的倍數都被篩掉了,剩下的就是素數。如下 const int n 1e...
素數判斷 埃氏篩法和尤拉篩法(線性篩法)
埃氏篩法的原理是 給出要篩數值的範圍n,找出以內的素數。先用2去篩,即把2留下,把2的倍數剔除掉 再用下乙個質數,也就是3篩,把3留下,把3的倍數剔除掉 接下去用下乙個質數5篩,把5留下,把5的倍數剔除掉 不斷重複下去 任何乙個大於1的自然數 n,如果n不是素數,都可以唯一分解成有限個素數的乘積。例...