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;
}

浙公网安备 33010602011771号