[Algorithm Fundamentals] AcWing 868. Sieve Prime Numbers (detailed)

insert image description here


Topic description

topic link
insert image description here

Ideas 1

Idea 1 (the simplest method): gradually filter out the numbers that are multiples of each number, so that after drying, the remaining numbers are prime numbers. For example, if 11 is not deleted, it means that 1~10 are not divisors of 11. The divisors of 11 are only 1 and itself, so 11 is a prime number.
insert image description here

Time complexity O(n * logn)
insert image description here

#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;//注意数据范围
int primes[N], cnt;
bool st[N];

void get_primes(int n) {
    
    
    for (int i = 2; i <= n; i++) {
    
    
        if(!st[i]) {
    
    
            primes[cnt++] = i;
        }
        for (int j = i + i; j <= n; j += i) {
    
    
            st[j] = true;
        }
    }
}

int main () {
    
    
    int n;
    cin >> n;
    get_primes(n);
    cout << cnt << endl;
    return 0;
}

Idea 2: Linear sieve method [use the smallest prime factor to sieve composite numbers]

#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int primes[N], cnt;
bool st[N];//质数则为false  否则为true

// 朴素做法
// void get_primes(int n) {
    
    
//     for (int i = 2; i <= n; i++) {
    
    
//         if(!st[i]) {//如果不是质数的话,就存起来
//             primes[cnt++] = i;
//         }
//         for (int j = i + i; j <= n; j += i) {
    
    
//             st[j] = true;//筛掉后面它的倍数
//         }
//     }
// }

void get_primes(int n) {
    
    
    for (int i = 2; i <= n; i++) {
    
    
        if(!st[i]) {
    
    //如果是质数的话,就加入的质数表里面去  
            primes[cnt++] = i;
        }   
       // primes[j] <= n / i == primes[j] * i <= n,而primes[j] * i就是所有要筛除的合数
        for (int j = 0; primes[j] <= n / i; j ++) {
    
    //枚举质数
            st[primes[j] * i] = true;// 合数 = i * pj (pj为小于 i 的最小质因子 
            if(i % primes[j] == 0) {
    
    
                break; //primes[j]一定是i的最小质因子 
            }//举个例子,对于一个数9,9*2=18将18标记为合数,循环继续;9*3=27将27标记为合数,
            //此时发现9%3=0,循环退出。如果将循环继续下去会出现筛除9*5=45的情况,
            //而45=15*3,在15时会被在筛去一次,故不可行
        }
    }
}
int main () {
    
    
    int n;
    cin >> n;
    get_primes(n);
    cout << cnt << endl;
    return 0;
}


Guess you like

Origin blog.csdn.net/weixin_49486457/article/details/123976183