7.13 线性筛素数

今天我们讲了一大堆数论的东西,目前本人稍微掌握一些的便是素数筛法,下面为了保护着珍贵的遗产,我决定写一篇博客来记录一下,

谈到素数筛法,相信大家岁熟悉的是暴力筛,我们大家只需要把数n的前1到sqrt(n)中所有的质数拿来和这个数n除一下看一下能否整除,如果能够整除,说明这个n是素数,然后就依次这样判定。

还有一种筛法是E筛,就是把每个数自己所有的倍数全部筛掉,当然其实你会发现我们只要把所有素数的倍数全部筛掉就可以了。

然后上面两种筛法都不是我们今天的重点,我们今天要讲的筛法是线性筛法——即通过某种方式使每个数都被自己的最小素因子筛去即可。注意:是最小的素因子!!!

算法实现

其实实现还是非常的简单了,我们从小到大依次枚举i,再枚举最小质因子pj,将i*pj筛去

而当i mod pj =0 时break出来,因为更大的pk,i*pk会被pj筛去而不是pk

举一个非常简单的例子,就是如果说现在我们正在检查数字6,我们正在用他筛去后面的一些合数,但是现在我们碰到了数字3,3是一个素数,并且6除3余0所以这时候我们应该把6break掉,因为在后面的后面早晚会碰见一个合数既被3整除又被6整除,就会被访问两次,为了降低复杂度先break掉就只是他访问了一次,节约了时间。

下面上一个代码:

大家看一看应该也就懂了:

#include<bits/stdc++.h>
using namespace std;
bool mark[1000005];
int p[1000005];
int main()
{
    memset(mark,false,sizeof(mark));
    int n;
    int cnt=0;
    scanf("%d",&n);
    for(int i=2;i<=n;++i)//枚举筛第i个数 
    {
        if(!mark[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&i*p[j]<=n;++j)
        {
            mark[i*p[j]]=true;
            if(i%p[j]==0) break;//important
        }
    }
    for(int i=1;i<=cnt;++i)
    {
        printf("%d ",p[i]);
    } 
    return 0;
}

原文链接: https://www.cnblogs.com/mudrobot/p/13330088.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    7.13 线性筛素数

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/367649

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 下午5:53
下一篇 2023年3月2日 下午5:54

相关推荐