【模板】筛质数

给定一个正整数n,请你求出1~n中质数的个数。

输入格式

共一行,包含整数n。

输出格式

共一行,包含一个整数,表示1~n中质数的个数。

数据范围

1≤n≤106

输入样例:

1
8

输出样例

1
4

模板

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1000010;

int n;
bool st[N];
int prime[N], cnt;

// void get_primes(int n) { // 朴素筛法 O(nlogn) 用素数和合数筛
// for(int i = 2; i <= n; i++) {
// if(!st[i]) prime[cnt++] = i;
// for(int j = i+i; j <= n; j += i)
// st[j] = true;
// }
// }


// void get_primes(int n) // 埃氏筛法 O(nloglogn) 用素数筛就行 合数可以用质因子筛掉
// {
// for(int i = 2; i <= n; i ++)
// if(!st[i])
// {
// prime[cnt ++] = i;
// for(int j = i+i; j <= n; j += i) st[j] = true;
// }
// }

//线性筛法-O(n), n = 1e7的时候基本就比埃式筛法快一倍了
//算法核心:合数仅会被其最小质因子筛去
/*
prime[]数组中的素数是递增的,当i能整除prime[j],那么i*prime[j+1]这个合数肯定被prime[j]乘以某个数筛掉。
因为i中含有prime[j],prime[j]比prime[j+1]小,即i=k*prime[j],那么i*prime[j+1]=(k*prime[j])*prime
[j+1]=k’*prime[j],接下去的素数同理。所以不用筛下去了。因此,在满足i%prime[j]==0这个条件之前以及第一次
满足改条件时,prime[j]必定是prime[j]*i的最小因子。
*/
void get_primes(int x) {
for(int i = 2; i <= x; i++)
{
if(!st[i]) prime[cnt++] = i;
for(int j = 0; prime[j] <= x / i; j++)
{
st[prime[j]*i] = true;
if(i % prime[j] == 0) break;
/*
1.i%pj == 0, pj定为i最小质因子,pj也定为pj*i最小质因子
2.i%pj != 0, pj定小于i的所有质因子,所以pj也为pj*i最小质因子
*/
}
}
}

int main()
{
scanf("%d", &n);

get_primes(n);

cout << cnt << endl;

return 0;

}

【模板】筛质数
https://piscesfinalizer.github.io/2021/03/07/【模板】筛质数/
作者
PiscesFinalizer
发布于
2021年3月7日
许可协议