AcWing 868. Sieve Prime Numbers
Since I am a number theory player in our team, I will be slightly biased towards QWQ in number theory during winter vacation. I will record 2021-01-12 here.
Three Prime Number Sieves
Linear sieve
Core idea: to
ensure that each number must be screened out by its smallest prime factor, time complexity AC code:O(n)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 10;
int primes[N];
bool st[N];
void get_primes(ll n) {
int cnt = 0;
for (int i = 2; i <= n; i++) {
if (!st[i]) {
primes[cnt++] = i;
// primes数组 存 筛选出来的质数
}
// 原理:筛除数的时候利用这个数的 最小质因子
// 每个数n,只会被它的最小质因子筛除
for(int j = 0; primes[j] <= n/i; j++) {
st[primes[j] * i] = true;
if(i % primes[j] == 0) // 这个判断意味着 primes[j] 一定是 i 的最小质因子 (从小到大的枚举)
break; // 同时 primes[j] 也一定是 primes[j] * i 的最小质因子
}
}
cout << cnt << endl; // cnt 代表筛选出的 质数数量
}
int main() {
ll n;
while (~scanf("%lld", &n)) {
if (n == 1) {
cout << 0 << endl;
continue;
}
get_primes(n);
// 如有需要,可以打出筛选出来的质数 primes数组
}
return 0;
}
Naive Sieve
AC code:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 10;
int primes[N];
bool st[N];
void get_primes(ll n) {
int cnt = 0;
for (int i = 2; i <= n; i++) {
if (!st[i]) {
primes[cnt++] = i;
// primes数组 存 筛选出来的质数
}
// 循环 筛选出 倍数
for (int j = i + i; j <= n; j += i) {
st[j] = true;
}
}
cout << cnt << endl; // cnt 代表筛选出的 质数数量
}
int main() {
ll n;
while (~scanf("%lld", &n)) {
if (n == 1) {
cout << 0 << endl;
continue;
}
get_primes(n);
// 如有需要,可以打出筛选出来的质数 primes数组
}
return 0;
}
Angstrom Sieve
The Angstrom sieve method is an optimization of the naive sieve method 时间复杂度为 O(nloglogn)
, that is, only the AC code of multiples of all prime numbers is filtered out
:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 10;
int primes[N];
bool st[N];
void get_primes(ll n) {
int cnt = 0;
for (int i = 2; i <= n; i++) {
if (!st[i]) {
primes[cnt++] = i;
// primes数组 存 筛选出来的质数
// 循环 筛选出 倍数
for (int j = i + i; j <= n; j += i) {
st[j] = true;
}
}
}
cout << cnt << endl; // cnt 代表质数数量
}
int main() {
ll n;
while (~scanf("%lld", &n)) {
if (n == 1) {
cout << 0 << endl;
continue;
}
get_primes(n);
// 如有需要,可以打出筛选出来的质数 primes数组
}
return 0;
}
Summary: The linear sieve method has the lowest time complexity and is recommended
The sieve method is more to provide a way of solving problems, and it will also be used in some other algorithmic problems.