欧拉质数筛

理解

是目前几乎最优的找质数方法,

例题_1

例题链接:https://www.acwing.com/problem/content/870/
给定一个正整数 n,请你求出 1∼n 中质数的个数。

题解

#include<bits/stdc++.h>
using namespace std;
int n;
//标记数组,标记合数
int mk[100000008];
//记录质数
int mem[1000006];
int idx , cnt;
void prime(int n)
{
    for(int i = 2 ; i <= n ; i++)
    {
        //没有被标记,说明是质数,标记并记录
        if(mk[i] == 0)
        {
            cnt++;
            mk[i] = i;
            mem[++idx] = i;
        }
        for(int j = 1 ; j <= idx ; j++)
        {
            //如果超出题目要求范围
            if(mem[j] * i > n || mem[j] > mk[i])
            {
                break;
            }
            //质数 * 非0非1数字 = 合数,标记
            mk[i * mem[j]] = mem[j];
        }
    }
}
int main()
{
    cin >> n;
    prime(n);
    cout << cnt << endl;
    return 0;
}

例题_2

例题链接:https://www.luogu.com.cn/problem/P3383

给定一个范围 n,有 q 个询问,每次输出第 k 小的素数

题解

#include<bits/stdc++.h>
using namespace std;
int n;
//标记数组,标记合数
int mk[100000008];
//记录质数
int mem[1000006];
int idx;
//欧拉质数筛
void prime(int n)
{
    for(int i = 2 ; i <= n ; i++)
    {
        //没有被标记,说明是质数,标记并记录
        if(mk[i] == 0)
        {
            mk[i] = i;
            mem[++idx] = i;
        }
        for(int j = 1 ; j <= idx ; j++)
        {
            //如果超出题目要求范围
            if(mem[j] * i > n || mem[j] > mk[i])
            {
                break;
            }
            //质数 * 非0非1数字 = 合数,标记
            mk[i * mem[j]] = mem[j];
        }
    }
}
int main()
{
    cin >> n;
    prime(n);
    int q;
    cin >> q;
    while(q--)
    {
        int k;
        cin >> k;
        cout << mem[k] << endl;
    }
    
    return 0;
}
posted @ 2022-08-02 10:17  Zilliax  阅读(46)  评论(0)    收藏  举报