[模板] 线性筛素数 (欧拉筛)

【模板】素数筛

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值