【模板】素数筛
P3383 【模板】线性筛素数 - 洛谷 | 计算机科学教育新生态
题目背景
本题已更新,从判断素数改为了查询第 k 小的素数
提示:如果你使用 cin
来读入,建议使用 std::ios::sync_with_stdio(0)
来加速。
题目描述
如题,给定一个范围 n,有 q个询问,每次输出第 k 小的素数。
输入格式
第一行包含两个正整数 n,q,分别表示查询的范围和查询的个数。
接下来 q 行每行一个正整数 k,表示查询第 k 小的素数。
输出格式
输出 q 行,每行一个正整数表示答案。
输入输出样例
输入 | 输出 |
---|---|
100 5 1 2 3 4 5 | 2 3 5 7 11 |
说明/提示
【数据范围】
对于 100% 的数据,n = 1e8,1≤q≤1e6,保证查询的素数不大于 n。
Data by NaCly_Fish.
代码
欧拉筛(线性筛)
#include <cstdio>
#include <vector>
using namespace std;
constexpr int MAX_N = 1e8;
bool prime_mark[MAX_N + 2];
vector<int> prime_list;
void init_prime(const int &);
void fread_int32(int & num){
num=0;
register bool f = false;
register char c = getchar();
while(c<'0'||c>'9'){if(c=='-')f=true;c=getchar();}
while(c>='0'&&c<='9'){num=(num<<3)+(num<<1)+c-'0';c=getchar();}
if(f) num = ~num + 1;
}
int n, m;
int main()
{
fread_int32(n);
fread_int32(m);
int temp;
init_prime(n);
for (int i = 1; i <= m; i++){
fread_int32(temp);
printf("%d\n", prime_list[temp-1]);
}
return 0;
}
void init_prime(const int &n){
prime_mark[0] = 1,prime_mark[1] = 1;
for (int i = 1; i <= n; i++){
// i是素数,将i加入素数表中
if (prime_mark[i] == false)
prime_list.push_back(i);
for (int j : prime_list){
// 超过筛的上线则停止
if (i * j > n)
break;
// 标记非素数
prime_mark[i * j] = true;
// i中含有因子j则停止(O(nlogn) -> O(n))
if (i % j == 0)
break;
}
}
}