埃氏筛与区间筛

埃氏筛

原理

根据算术基本定理,每个大于1的数都可以分解成若干个质数的乘积,所以对于一个不是质数的数,只需判断它有质因数即可。埃氏筛(埃拉托斯特尼筛法)其实就是上述过程的逆过程:每枚举到一个质数便把这个质数的倍数打上不是质数的标记。

实现

具体如下:

//筛出1~n的质数
for(int i = 2; i * i <= n; i++){ //只需枚举到sqrt(n)
		if(!v[i]){
			for(int j = i + i; j * j <= n; j += i){
				v[j] = 1;
			}
		}
		
	}

区间筛

一般筛质数是筛出 1~n 内的质数,有些时候需要找一个区间内质数的个数,而左右边界又比较大,不能直接用前缀和相减算出。例如:

洛谷P1835 素数密度
给定区间[L,R] (L <= R < 2^31,R - L <= 10^6) ,请计算区间中素数的个数。

做法

运用埃氏筛的原理,对于枚举的每个质数,在 1~n 内筛质数的同时,也在 L~R内筛。

//核心代码:
for (int i = 2; ((ll)i * i) <= m; i++) {
   	if (!v[i]) {
   		for (int j = 2 * i; ((ll)j * j) <= m; j += i)
   			v[j] = 1;
   		int k; 
//最主要的是初始值,并不是从n开始筛起,而是从[n,m]中第一个质数i的倍数开始
   		if (n % i == 0)
   			k = n;
   		else {
   			k = n / i;
   			k = k * i + i;
   		}
   		for (ll j = k; j <= m; j += i) {
   			vis[j - n] = 1;
   		}
   	}
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值