洛谷P3383 欧拉线性筛素数

题目:

先讲算法原理:

  1. 任何一个合数都存在唯一的最小质因子,
  2. 对于从小到大枚举的质数pj,如果\(i\%pj == 0\)则pj一定是\(i*pj\)的最小质因子
    如果\(i\%pj != 0\)则pj一定是\(i*pj\)的最小质因子
    对于任何一个合数,我们都使用它的最小质因子去筛它(是或者不是),因为每个合数只有一个最小质因子,所以它的时间复杂度是O(n)的
#include <cstdio>
using namespace std;
int n, q, k;
constexpr int N = 1e6 + 10;
bool st[N];
int primes[N];
int idx = 0;
inline void init(int n) {
    memset(st, false, sizeof st);
    // ouler
    for(int i = 2; i <= n; ++i) {
        if(!st[i]) {
            primes[idx++] = i;
        }
        for(int j = 0; primes[j] <= n / i; ++j) {
            st[primes[j] * i] = true;
            if(i % primes[j] == 0) {
                break; // 此处保证了前面i*primes[j]中的primes[j]不是i的质因子,因此i*primes[j]的最小质因子是primes[j]
            }
        }
    }
    
    
}
int main() {
    scanf("%d%d", &n, &q);
    init(n);
    for(int j = 0; j < q; ++j) {
        scanf("%d", &k);
        printf("%d\n", primes[k - 1]);
    }
}
posted @ 2024-03-05 19:13  ccnju  阅读(17)  评论(0)    收藏  举报