欧拉筛
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <iostream> #include <cstdio>
int n; int cnt, prime[1003]; bool is_prime[100005];
void Ols() { for(int i = 2; i <= n; i ++) is_prime[i] = 1; for(int i = 2; i <= n; i ++) { if(is_prime[i]) prime[++ cnt] = i; for(int j = 1; j <= cnt; j ++) { is_prime[i * prime[j]] = 0; if(i % prime[j] == 0) break; } } }
int main() { scanf("%d", &n); Ols(); for(int i = 1; i <= cnt; i ++) printf("%d%c", prime[i], " \n"[i == n]); return 0; }
|
第20行为什么要break
欧拉筛保证为线性的关键就在于这个break, 在欧拉筛中, 每个合数只会被弃最小的质因子筛一次, 如果当前的i是prime[j]的倍数关系, 那么当j变为j加1时,$ i \times prime[j+1]$就相当于是用prime[$j + 1$]筛出, 但是显然这个数应该被prime[j]筛, 不满足了要求, 也就不再是线性。
举个例子
当前i=4, prime[j]为2,用$2 \times 4$更新8后, 如果不break, 那么就会用下一个质数3继续更新, 即用$3 \times 4$更新了12, 此时这个12是用3更新的, 但实际上12的最小质因子是2, 所以12应该被$2 \times 6$更新一次, 导致12被3更新的就是4是2的倍数, 所以一定要break。