算法介紹:歐拉篩法是在O(N)線性時間內實現素數篩選的優秀算法。
算法思路:總體上與Eratosthenes篩法類似,也是用較小的數篩去較大的合數。
關鍵思路在於:每一個合數都保證是被其最小的質因子篩去的,下簡稱稱該條件為線性條件。
結合代碼分析:
inline void Euler_Sieve(){
for(register int i=2;i<=n;i++){
if(isPrime[i]) pri[++cnt]=i;
for(register int j=1;j<=cnt&&i*pri[j]<=n;j++){
isPrime[i*pri[j]]=false;
if(i%pri[j]==0) break;
}
}
}
對每一個數i,無論其是否為質數,都可以用其篩去其他數。
j 循環到 i % Prime[j] = 0就恰好需要break的理由是:
設1<=s<j<t
證明:若最小質因子比pri[j]小,則在循環到j之前就已break,不可能循環至pri[j]。
證明:引理1已證i的最小質因子為pri[j],故i*pri[j]最小質因子也應為pri[j]。引理2保證了被pri[j]篩掉的所有合數都滿足線性條件。
證明方法如引理1。引理3保證了j之前所有被篩掉的合數都滿足線性條件。
證明方法:由引理1可易證。故若j繼續循環增大,則i*pri[t]將被pri[t]篩掉,但pri[t]並非其最小質因子,故不滿足線性條件,故需break。
綜上,當i%pri[j]==0的時候實行break操作可保證滿足線性條件,實現線性篩。