埃氏筛法与欧拉筛法

题目

给出区间[1,n],统计其间的素数个数
n<10^8

思路

埃氏筛法

最小的素数是2,那么2的整数倍都不是素数,删去4,6,8…
余下的数里,最小的素数是3,删去6,9,12…
最终未被删去的数就是素数
但,这样在效率上有一个问题:一个数会被删去多次
例如42会被2 3 7都删去一遍
其时间复杂度为O(NlogNlogN)

for( int i=2;i<=n;i++ )
	if( !death[i] ) {
		death[i]=1;
		for( int k=2;k*i<=n;k++ )
			death[k*i]=1;
	}
		

欧拉筛法

对每个合数a×b,它会被每个质因数都筛去一遍
但我们只要用最小的质因数筛去就好了
为此,我们需要记录下所产生的全部素数,代码如下

for( int i=2;i<=n;i++ ) {
	if( !death[i] )
		primelist[++tail] = i;//record this new prime
	for( int k=1;k<=tail;k++ ) {
		if( primelist[k]*i > n ) break;
		death[primelist[k]*i] = 1;
		if( i%primelist[k] == 0 ) break;//!!!
	}	

}

核心就是

if(i%primelist[k]==0) break;

如果i能整除primelist[k],
说明primelist[k]是i的因子,
所以primelist[k]也是i的任意倍数的因子。
所以primelist[k]也是i×primelist[x] (x>k)的因子。
考虑到primelist单增,对i×primelist[x],primelist[k]就是它的比primelist[x]更小的因子。
故不用考虑其后的质因子了。
(i×primelist[x]会被primelist[k]作为因子在i更大时被筛掉)

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值