线性筛详解

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

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值