P3382 线性筛素数

【模板】线性筛素数

题目描述

如题,给定一个范围 \(n\),有 \(q\) 个询问,每次输出第 \(k\) 小的素数。

输入格式

第一行包含两个正整数 \(n,q\),分别表示查询的范围和查询的个数。

接下来 \(q\) 行每行一个正整数 \(k\),表示查询第 \(k\) 小的素数。

输出格式

输出 \(q\) 行,每行一个正整数表示答案。

样例 #1

样例输入 #1

100 5
1
2
3
4
5

样例输出 #1

2
3
5
7
11

提示

【数据范围】
对于 \(100\%\) 的数据,\(n = 10^8\)\(1 \le q \le 10^6\),保证查询的素数不大于 \(n\)

线性筛素数要注意几个点:

1. 每次从prime[]中选出来扩展

2. if(i%prime[j])break 且 要写在后面

这两个要点是保证筛法的线性复杂度的基础!!!

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,q,k;
int prime[6000005],cnt;
bool notp[100000005];
inline int read() {
	int x=0,f=1;
	char ch=getchar();
	while(ch<48||ch>57) {
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>=48&&ch<=57)
		x=10*x+ch-48,ch=getchar();
	return x*f;
}
void init(int n) {
	notp[1]=1;
	for(int i=2; i<=n; i++) {
		if(!notp[i])prime[++cnt]=i;
		for(int j=1; j<=cnt; j++) {
			if(i*prime[j]>n)break;
			notp[i*prime[j]]=1;
			if(i%prime[j]==0)break;
		}
	}
}
signed main() {
	ios::sync_with_stdio(false);
	n=read(),q=read();
	init(n);
	while(q--) {
		k=read();
		cout<<prime[k]<<"\n";
	}
	return 0;
}
posted @ 2023-04-05 14:36  N0zoM1z0  阅读(36)  评论(0)    收藏  举报