【模板】线性筛素数

例题洛谷P3383
原理大概是在如2的倍数不是素数,3的倍数不是素数这样来排除素数时,会出现重复排除比如6。
线性筛素数避免了重复排除 实现了O(n)时间复杂度
贴一个洛谷题解代码

#include<cstdio>
#include<iostream>
using namespace std;
int check[100000001];
int prime[1000001];
int main()
{
	int n,q;
	int cnt=0;
	//根据n<=10^8,q<=10^6开对应的数组大小,防止MLE
	//初始将check数组全部标记为0,标0的是素数,标1的不是素数
	scanf("%d%d",&n,&q);
	check[1]=1;//1不是素数
	for(int i=2;i<=n;i++)
	{
		if(!check[i])prime[cnt++]=i;//若当前数i没有被之前的所有数筛掉,表明i是素数,将i添加进素数表prime
		for(int j=0;j<cnt&&i*prime[j]<100000001;j++)//注意i*prime[j]不要超过n的上限(10^8)
		{
			check[i*prime[j]]=1;//将当前素数prime[j]的i倍标记为合数
			if(i%prime[j]==0)break;//关键步骤:保证每个合数只被筛一次
		}
	}
	for(int i=1;i<=q;i++)
	{
		scanf("%d",&n);
		printf("%d\n",prime[n-1]);//由于素数表从0开始存,所以输出时下标应减1
	}
	return 0;
}
posted @ 2020-10-07 21:28  一个经常掉线的人  阅读(89)  评论(0)    收藏  举报