线性筛详解

线性筛可以做到 O(n)的复杂度筛出所有素数。

其基本原理:任何合数都能被表示成一系列素数的积。

如果你了解了 O(nlogn) 的 Eratosthenes 筛法,你就会发现其实每个数都会被多次筛到。

本算法保证每个合数只会被他的最小素因子筛到一次,所以可以做到线性复杂度。

详解见代码,这样是可以保证每个数仅被筛到一次的。

const int N = 10000;
int lp[N],primes[N],pcnt;
//lp[i]:i 的最小素因子
//pcnt:记录多少个素数
//primes:记录素数
inline void sieve(){
    pcnt = 0;
    memset(lp,0,sizeof(lp));
    for(int i=2;i<=N;++i){
        int& l = lp[i];//取地址符,修改l等价于修改lp[i] 
        if(l == 0)l = i,primes[pcnt++] = i;//没有最小素因子,那么他就是个素数 
        for(int j=0;j<pcnt&&primes[j] <= l;++j){//遍历存过的素数 当作最小素因子 
            int p = primes[j];//对应循环条件的p <= l 如果超出去了那么就不是最小素因子 
            if(i * p >= N)break;
            lp[i * p] = p; //i*p的最小素因子是p 
        }
    }
}

 

posted @ 2022-03-20 11:55  Xu_brezza  阅读(74)  评论(0编辑  收藏  举报