筛质数的三种方法
朴素筛法O(nlogn)
朴素筛法的原理就是从小到大枚举每次将数的倍数都筛掉,因为只要是合数那他一定就会有因子,而如果是从小到大枚举这样就可以将1~n中的所用合数都筛掉,这样剩下的数就都是质数了
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1000010;
bool st[N];
int cnt;
int prime[N];
// 朴素筛法
void get_primes(int n)
{
for (int i = 2; i <= n; i ++)
{
if (!st[i])
prime[cnt ++] = i;
for (int j = i; j <= n; j += i)
st[j] = true;
}
}
int main ()
{
int n;
scanf("%d", &n);
get_primes(n);
cout << cnt << endl;
return 0;
}
埃式筛法 O(nloglogn)
// 埃式筛法
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i])
{
prime[cnt ++] = i;
for (int j = i; j <= n; j += i )
st[j] = true;
}
}
}
算法的核心原理是:每次用最小的质因子筛掉每一个数st[prime[j] * i ] = true
线性筛法O(n)
// 线性筛法
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
// 当i % prime[j] == 0的时候,这时prime[j]就是i的最小质因子
// 当i % prime[j] != 0的时候,这时prime[j]比i的最小质因子还小
// 所以也可以用来筛质数
}
}
}
当数据<=107的时候埃式筛法和线性筛法差不多,但是当>=107的时候线性筛法明显要比埃式筛法快一倍,所以通常筛素数都是用线性筛法