線性篩法


關於線性篩法

線性是指O(n)內篩掉所有合數,還有一種方法叫埃氏篩法,我先證明埃氏篩法效率低,也就是會有重復。

證明如下:

埃氏篩法的原理是找到一個素數后,它的1~n倍就會被篩掉,任何一個合數都可以被拆成一個質數*另一個數的形式,我們對每一個質數對應的可能的(合)數都枚舉了,這就保證了所有可能的合數都被篩掉了。為什么不是最優呢?問題出在那個質數上,對於一個合數m,m=h*P,P是質數且P>m的最小質因數,那么m也可以表示為m=H*p,(H是個比h大的合數,p是m的最小質因數),這樣我們在枚舉p的倍數時,m就被篩掉了,而在枚舉P的倍數時,m又被篩掉了一次,造成效率浪費。

怎辦呢?--------線性篩法

我們在枚舉倍數時,保證當前質數不能整除這個倍數就好了,當然了,在之前要先篩一次,也就是p是m的p,這樣我們在最優性的條件下,對每一個質數,它所有對應的倍數,都被枚舉到,也就保證了可行性。

代碼如下:

#include<bits/stdc++.h>
using namespace std;
int n,cnt;
int prime[100000];
bool vis[100000];

void Euler(){
    for(int i=2;i<=n;i++){
        if(!vis[i]) prime[++cnt]=i;
        for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
            break;
        }
    }
}

int main(){
  cin>>n;
  Euler();
  for(int i=1;i<=cnt;i++)
  cout<<prime[i]<<' ';
  return 0;
}

里面關鍵就是那個break,如果不break,就是再往大里枚舉,那么以后枚舉到的質數,一定不是最小質數,因為它都比當前質數大了,怎么可能最小,最小也只可能是當前的質數,從而實現了優化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM