//#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 imes prime[j] <= n) 因为循环内用到了这个乘
最重要的是最后一句 (i mod prime[j] == 0) 这句话是什么意思
我们可以假设没有这句话,那么当发生 (imod prime[j] == 0) 的时候,我们就知道 这个 (i) 必定包含 (prime[j]) 这样也就说明了此时 (i) 是 (prime[j]) 的最小因子,当到 (prime[j + 1]) 的时候,我们知道 (i) 是 (prime[j]) 的因子,原式子就可以改写成 (prime[j + 1] imes i = prime[j + 1] imes k imes prime[j]) 如果不跳过(i mod prime[j]) 这里就会进行重复标记,很明显 这是我们不想看到的