素数筛

给定一个正整数 nn,请你求出 1n1∼n 中质数的个数。

输入格式

共一行,包含整数 nn。

输出格式

共一行,包含一个整数,表示 1n1∼n 中质数的个数。

数据范围

1n1061≤n≤106

输入样例:

8

输出样例:

4

素数:只有1和本身的因子成为素数,也称质数

求素数的一种方法试除法:按照其定义来,枚举1到n-1没有可以被整除的数,优化为1到sqrt(n)

埃氏筛法:

从2开始,把每一个2的倍数筛掉,3的倍数晒掉,(4被筛了),5的倍数筛掉....

这样留下来的就都是素数,因为没有被筛掉,所以令这个数为p不是2到p-1的数的倍数,也就是没有约数,那就是素数:

优化:可以把每个质数的倍数筛掉就可以了

因为一个合数可以质因数分解,把质数的倍数筛掉,那筛去的就都是合数,也就是一个合数必然被前面的质数给筛掉,所以剩下来的也就都是素数

复制代码
#include<iostream>
using namespace std;
const int N=1e6+10;
int prime[N],cnt;//存素数及其个数
bool st[N];//筛子
void primes(int n)
{
    for(int i=2;i<=n;i++)//从2开始筛 
    {
        if(st[i]) continue;//合数就跳过,筛质数的倍数
        prime[cnt++]=i;//存质数及其个数
        for(int j=i+i;j<=n;j+=i) st[j]=true;//筛掉 
    }
    cout<<cnt<<endl;
} 
int main(){
    int n;
    cin>>n;
    primes(n);
    return 0;
}
复制代码

 线性筛法:

核心:n只会被最小质因子筛掉

 

用最小质因子来筛,每一个数都只有一个最小质因子,所以所有的合数都会被筛掉,所以是线性的

复制代码
#include<iostream>
using namespace std;
const int N=1e6+10;
int prime[N],cnt;//存素数及其个数 
int st[N];//筛子
void primes(int n)
{
    for(int i=2;i<=n;i++)//筛所有的n以内的素数 
    {
        if(!st[i]) prime[cnt++]=i;//如果是素数就存起来
        for(int j=0;prime[j]<=n/i;j++)//从0开始枚举素数,等价于prime[j]*i<=n,当然啊,总共才到n个
        {
            st[prime[j]*i]=true; 
            if(i%prime[j]==0) break;//如果此时的素数被i整除,那这个素数就是i的最小质因子 
        } 
    }
}
int main(){
    int n;
    cin>>n;
    primes(n);
    cout<<cnt<<endl;
    return 0;
}
复制代码

这个我不好表述...不会的时候看acw最高赞题解吧,写的很清楚

posted @   小志61314  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示