Number theory sieve prime numbers

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.

Insert picture description here

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

Insert picture description here
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
Insert picture description here
:

#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.

Guess you like

Origin blog.csdn.net/qq_45654671/article/details/112518935