P1835 素数密度(区间筛)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1835 素数密度(区间筛)相关的知识,希望对你有一定的参考价值。

P1835 素数密度(区间筛)

因为区间长度只有 1 e 6 1e6 1e6,考虑筛掉里面的合数。

因为值域很大,但是我们知道晒到 [ 1 , r ] [1,r] [1,r]里面的合数只需要 r \\sqrtr r 里面的质数即可。

因此我们可以预处理这部分,然后用这些质数去筛区间 [ L , R ] [L,R] [L,R]

时间复杂度: O ( m + m l o g R ) O(m+mlogR) O(m+mlogR)

// Problem: P1835 素数密度
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1835
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// Date: 2022-03-06 19:42:39
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=1e6+5,M=5e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define db double
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

bitset<M>vis;
int p[M],cnt;
void ss(int n)
	vis[0]=vis[1]=1;
	for(int i=2;i<=n;i++)
		if(!vis[i]) p[++cnt]=i;
		for(int j=1;j<=cnt&&i*p[j]<=n;j++)
			vis[i*p[j]]=1;
			if(i%p[j]==0) break;
		
	

bitset<N>jg;
int main()
	int l,r;
	scanf("%d%d",&l,&r);
	if(l==1) l = 2;
	ss((int)sqrt(r));
	for(int i=1;i<=cnt;i++)
		ll v = (l+p[i]-1)/p[i]*p[i];
		if(v< 2*p[i]) v = 2*p[i];
		for(ll j=v;j<=r;j+=p[i]) jg[j-l+1]=1;
	
	int ans = 0;
	for(int i=1;i<=r-l+1;i++) if(!jg[i]) ans++;
	printf("%d\\n",ans);
	return 0;


以上是关于P1835 素数密度(区间筛)的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P1835 素数密度_NOI导刊2011提高(04)题解

[luoguP1835] 素数密度_NOI导刊2011提高(04)(素数筛)

CodeVS3223素数密度

68测试20161117数论乱搞前缀和

codevs3223素数密度

素数筛( 埃氏筛线性筛区间筛)