当只需要判断某个数是不是素数的时候,我们可以直接通过素数的定义来求,但是如果要求某个范围内的素数的个数的时候这个方法就不太合适了。虽然我们可以进行预处理,但是这种方法比较慢,一旦范围过大,预处理过程便会超时。这时候就引入了一种新的简单检定素数的方法-----埃拉托斯特尼筛法
埃拉托斯特尼筛法
从2开始,将每个素数的各个倍数(一倍除外),标记成合数。一个素数的各个倍数,是一个差为此素数本身的等差数列。此为这个筛法和试除法不同的关键之处,后者是以素数来测试每个待测数能否被整除。埃拉托斯特尼筛法(英语:sieve of Eratosthenes ),简称埃氏筛,也称素数筛。这是一种简单且历史悠久的筛法,用来找出一定范围内所有的素数。埃拉托斯特尼筛法是列出所有小素数最有效的方法之一。
算数基本定理
每个整数 n >= 2 可唯一分解成素数乘积 n = p1p2…pr.
普通线性筛法
由算数基本定理可知,任何一个大于等于 2 的数,都可以表示成两个数相乘的形式,只有 1 和 它本身这一对组合的是素数,剩下的都是合数。对于一个合数 a,则一定等于某个素数 b 与另一个素数或者合数 c 相乘。也就是换句话说,通过筛掉所有素数的倍数,就可以将所有的合数筛掉而只剩下素数,于是有了如下的普通线性筛法。#include <stdio.h>
#include <string.h>
#define MAX (int)1e5 //待判断素数范围0~MAX
#define ll long long
ll prime[MAX + 1], cnt;
bool isPrime[MAX + 1];
void init_prime()
{
cnt = 1;
memset(isPrime, 1, sizeof(isPrime)