素数线性筛法 → 欧拉筛

【题目来源】
https://www.acwing.com/problem/content/870/

【题目描述】
给定一个正整数 n,请你求出 1∼n 中质数的个数。

【输入格式】
共一行,包含整数 n。

【输出格式】
共一行,包含一个整数,表示 1∼n 中质数的个数。

【数据范围】
1≤n≤10^6

【输入样例】
8

【输出样例】
4

【算法分析】
普通的素数筛法,即将给定的数 n 以内的所有数 x 的倍数 kx(k≥2) 都筛掉。
显然由下图可知,同一个数可能被多个素数
重复筛掉。如下图中的 6、12 被重复筛掉。
这需要优化,
欧拉筛便是一种素数的线性筛法。原理是让每个合数只被它的最小质因数筛掉,这样每个合数只会被筛选一次。

 【算法代码】

#include <bits/stdc++.h>
using namespace std;

const int maxn=1e6+5;
int p[maxn];
bool st[maxn];
int cnt;

void getNum(int n) {
    for(int i=2; i<=n; i++) {
        if(!st[i]) p[cnt++]=i;
        for(int j=0; p[j]*i<=n; j++) {
            st[p[j]*i]=true;
            if(i%p[j]==0) break;
        }
    }
}

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

/*
in:8
out:4
*/

【参考文献】
https://zhuanlan.zhihu.com/p/494328631
https://www.acwing.com/solution/content/7950/





 

猜你喜欢

转载自blog.csdn.net/hnjzsyjyj/article/details/132352060