其实这题或许还有更快解(尽管用了vector)常熟大
查看原帖
其实这题或许还有更快解(尽管用了vector)常熟大
922855
littlep001楼主2024/5/1 18:08

steve of atkin 速度 O(n/loglogn)O(n/loglogn)

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

vector<int> atkin_sieve(int limit) {
    if (limit < 2) return {};

    vector<bool> is_prime(limit + 1, false);
    vector<int> primes;

    // Preliminary sieve for primes up to the square root of the limit
    int sqrt_limit = sqrt(limit);
    vector<bool> preliminary(limit + 1, false);

    for (int x = 1; x <= sqrt_limit; x++) {
        for (int y = 1; y <= sqrt_limit; y++) {
            int n = (4 * x * x) + (y * y);
            if (n <= limit && (n % 12 == 1 || n % 12 == 5))
                preliminary[n] = !preliminary[n];

            n = (3 * x * x) + (y * y);
            if (n <= limit && n % 12 == 7)
                preliminary[n] = !preliminary[n];

            n = (3 * x * x) - (y * y);
            if (x > y && n <= limit && n % 12 == 11)
                preliminary[n] = !preliminary[n];
        }
    }

    // Mark all multiples of squares as non-prime
    for (int n = 5; n <= sqrt_limit; n++) {
        if (preliminary[n]) {
            int x = n * n;
            for (int k = x; k <= limit; k += x) {
                preliminary[k] = false;
            }
        }
    }

    // Add remaining primes to the primes vector
    primes.push_back(2);
    primes.push_back(3);
    for (int n = 5; n <= limit; n++) {
        if (preliminary[n]) {
            primes.push_back(n);
        }
    }

    return primes;
}

int main() {
    int n, q;
    cin >> n >> q;
    vector<int> primes = atkin_sieve(n);
    while (q--) {
        int k;
        cin >> k;
        cout << primes[k - 1] << endl;
    }
    return 0;
}
2024/5/1 18:08
加载中...