『数论』线性筛质数

//#define fre yes

#include <cstdio>

const int N = 100005;
int prime[N], isNotprime[N];

void isprime(int n) {
    int cnt = 0;
    isNotprime[1] = 1;
    for (int i = 2; i <= n; i++) {
        if(!isNotprime[i]) prime[++cnt] = i;
        for (int j = 1; j <= cnt && i * prime[j] <= n; j++) {
            isNotprime[i * prime[j]] = 1;
            if(i % prime[j] == 0) break;
        }
    }
}

谈论数论不废话 ----- 线性筛

以上代码的时间复杂度是 \(O(n)\)

需要注意以下几点

  • 1为素数,不为质数
  • 如果当前不是素数,那么一定是质数(显然可得)
  • 第二层循环中 为什么是 \(i \times prime[j] <= n\) 因为循环内用到了这个乘

最重要的是最后一句 \(i \mod prime[j] == 0\) 这句话是什么意思

我们可以假设没有这句话,那么当发生 \(i\mod prime[j] == 0\) 的时候,我们就知道 这个 \(i\) 必定包含 \(prime[j]\) 这样也就说明了此时 \(i\)\(prime[j]\) 的最小因子,当到 \(prime[j + 1]\) 的时候,我们知道 \(i\)\(prime[j]\) 的因子,原式子就可以改写成 \(prime[j + 1] \times i = prime[j + 1] \times k \times prime[j]\) 如果不跳过\(i \mod prime[j]\) 这里就会进行重复标记,很明显 这是我们不想看到的

posted @ 2019-10-21 10:08  Nicoppa  阅读(188)  评论(0编辑  收藏  举报