线性筛详解
线性筛可以做到 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 } } }