题目传送门

一、理解与感悟

先去掉\(2\)的倍数,再去掉\(3\)的倍数,再去掉\(4\)的倍数,……依此类推,最后剩下的就是素数。

如求\(100\)以内的素数,我们只要到去掉\(sqrt(100)\)的倍数就可以了,这是因为\(10\)\(2\)倍已经被\(2\)的倍数去掉了,\(10\)\(3\)倍已经被\(3\)的倍数去掉了,所以到\(10\)的时候只剩下\(10\)\(10\)倍以上的素数还存在。

同样的原因,我们在去掉\(3\)的倍数的时候,只要从\(3\)的3倍开始去掉就好了,因为\(3\)\(2\)倍已经被\(2\)的倍数去掉了。

AcWing 868. 筛质数

二、埃氏筛法

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;
int primes[N], cnt;     // primes[]存储所有素数
bool st[N];             // st[x]存储x是否被筛掉
//埃拉筛
void get_primes(int n) {
    for (int i = 2; i <= n; i++)
        if (!st[i]) {
            primes[cnt++] = i;   //记录素数
            for (int j = 2 * i; j <= n; j += i) //成倍数的标识
                st[j] = true;
        }
}


int main() {
    //读入优化
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    get_primes(n);
    cout << cnt << endl;
    return 0;
}

三、欧拉筛[线性筛法]

#include <bits/stdc++.h>

using namespace std;

//欧拉筛
const int N = 1e6 + 10;
int primes[N], cnt;     // primes[]存储所有素数
bool st[N];             // st[x]存储x是否被筛掉
void get_primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!st[i]) primes[cnt++] = i;
        for (int j = 0; primes[j] * i <= n; j++) {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

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

相关文章:

  • 2021-06-26
  • 2019-08-12
  • 2021-06-08
  • 2021-08-13
  • 2019-09-05
  • 2021-09-02
  • 2021-12-09
猜你喜欢
  • 2020-10-07
  • 2018-10-17
  • 2021-11-02
  • 2021-11-02
  • 2021-11-17
  • 2021-11-28
  • 2021-11-17
  • 2020-06-15
相关资源
相似解决方案