P3383 【模板】线性筛素数

#include<bits/stdc++.h>
#define ll long long  // 定义长整型别名,方便使用
using namespace std;

const int N = 1e8+10;  // 筛素数范围的上限
int pre[N / 10], k;    // pre数组存储素数,k记录素数个数
bool vis[N];           // 标记数组,vis[i]=true表示i不是素数

// 欧拉筛法(线性筛)实现
void ola()
{
    for(int i = 2; i < N; i++)  // 从2开始遍历每个数
    {
        if(vis[i] == 0)         // 如果i是素数
            pre[++k] = i;       // 将i存入素数数组
        
        // 用当前已找到的素数筛去合数
        for(int j = 1; j <= k; j++) 
        {
            // 防止pre[j]*i超出数组范围
            if(pre[j] > N / i) break;  
            
            // 标记pre[j]*i为合数
            vis[pre[j] * i] = 1;  
            
            // 关键优化:保证每个合数只被最小质因子筛去
            if(i % pre[j] == 0) break;
        }
    }
}

int main()
{
    // 预处理筛出所有素数
    ola();
    
    // 输入处理
    int n, q; 
    cin >> n >> q;  // n为范围,q为查询次数
    
    while(q--)
    {
        int k; 
        cin >> k;          // 查询第k小的素数
        cout << pre[k] << endl;  // 直接输出预处理结果
    }
    return 0;
}

 

posted @ 2025-04-24 16:38  CRt0729  阅读(20)  评论(0)    收藏  举报