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

欧拉筛算法可以在O(N)时间内对1~N范围内的数字进行判断并标记其是否为素数.

基于这样的思想:

  • 一个质数的x倍(x>1且为整数)一定不是质数.
  • 反过来,如果一个数不是任何一个质数的x倍(x>1且为整数),那么其一定是质数.

然而要保证线性复杂度,需要在实现上进行很多细节处理.具体的解释看别人写的博客来的快.

实现保证每当一个合数 i * s[j] 被筛除时,s[j]为该合数的最小质因数,i为该合数的最大非自身因数.

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

bool isPrime[100000010];        // 本题的空间限制为512MB, 时间限制为2s
int n, q;
vector<int> s;

// 执行此函数后,可以通过isPrime[x]查询x是否为素数,也可以查询第x个质数s[x]
// 如果不需要后一项功能,可以把s的声明放到这个函数里
void init(int n) {
    fill(isPrime, isPrime + 100000010, 1);
    isPrime[1] = isPrime[0] = 0;

    for (int i = 2; i <= n; i++) {
        if (isPrime[i]) s.push_back(i);
        for (int j = 0; j < s.size() && i * s[j] <= n; j++) {
            isPrime[i * s[j]] = 0;
            if (i % s[j] == 0) break;
        }
    }
}

int main() {
    scanf("%d%d", &n, &q);
    init(n);

    while (q--) {
        int k;
        scanf("%d", &k);
        printf("%d
", s[k - 1]);       // 第 "k" 小
    }

    return 0;
}

欧拉筛 P3383
欧拉筛 P3383
原文地址:https://www.cnblogs.com/Gaomez/p/14371306.html