题解 P3912 【素数个数】

· · 题解

这题是线性筛素数的模板题啊。。。

线性筛的主要思想是用O(N)的时间判断1...N中的每一个数是不是素数,也就是说用平均O(1)的时间判断一个数是不是质数。

具体实现如下:对从2到sqrt(N)中的每一个素数,将他们的所有倍数标记为合数。这样处理完后,没有被标记为合数的数就是质数了。

请看代码中的详细注释:

#include<cstdio>
using namespace std;
const int maxn=100000000;
bool tf[maxn];//判断是否是素数,如果i是素数,tf[i]是false,反之为true
int n,ans;//ans是最后的结果(你看我连前缀和都懒得写了),初始值为0
int main()
{
    scanf("%d",&n);
    for(register int i=2;i*i<=n;i++)//枚举i从2...sqrt(N)的所有值,写成i*i<=n的形式更快一些,register很重要
    {
        if(tf[i])continue;//如果tf[i]是true的话,也就是说i是合数,那么i的所有倍数都被标记过了,直接跳过,保证了时间复杂度
        for(register int j=2;i*j<=n;j++)tf[i*j]=true;//对i的所有不大于N的倍数进行标记
    }
    for(register int i=2;i<=n;i++)if(!tf[i])ans++;//从2...N,如果有一个数是素数,那么ans++
    printf("%d\n",ans);
    return 0;
} 

做完这题的小伙伴可以尝试一下 Luogu 3383