『数论』线性筛质数
//#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]\) 这里就会进行重复标记,很明显 这是我们不想看到的