素数筛

什么是素数筛?

素数筛是一种求所有小于n的所有素数的方法,把从2开始的所有合数逐步筛掉留下素数。

埃氏筛

埃氏筛的思路非常简单,从2开始筛去2的所有倍数,接着从剩下的最小数字3开始,筛去3的所有倍数,依次下去,每一次都筛去上一次剩下的数中最小的数k的所有倍数,最后剩下的数就是2~n中所有的素数。

那为什么剩下的数中最小的就一定是素数呢?因为一个数的因子一定是不超过其本身的,而小于这个数的所有倍数均已经被筛去了,所以剩下的数中最小的就一定是素数。

埃氏筛实现

bool vis[MAXN]; //用于标记下标i是否是素数
int prime[MAXN], x; //prime用于存放素数,x是prime数组的下标指针
void PrimeFilter(int n){ //埃氏筛 时间复杂度:O(nloglogn)
    vis[0] = vis[1] = true;
    for(int i = 2; i <= n; i++){
        if(!vis[i])prime[x++] = i;
        for(int j = 2; j * i <= n; j++)vis[i*j] = true; //将这个素数的所有倍数筛掉
    }
}

欧拉筛

在埃氏筛的步骤中我们可以发现,一个合数可能被多次筛去,比如6,即是2的倍数,也是3的倍数,被筛去了两次,这样浪费了很多时间。欧拉筛的基本思想就是让每个合数只被它的最小质因数筛去一次,避免重复。

欧拉筛实现

void EulaFilter(int n){ //欧拉筛
    vis[0] = vis[1] = true;
    for(int i = 2; i<=n; i++){
        if(!vis[i])prime[x++] = i;
        for(int j = 0; j < x; j++){
            if(i * prime[j] > n)break;
            vis[i * prime[j]] = true;
            if(i % prime[j] == 0)break;
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 问题:给出一个数n,输出1~n之间的素数 素数筛埃拉托斯特尼筛法每次消去的倍数,直到没有可消的为止,剩下的数字则为...
    雨落八千里阅读 1,716评论 0赞 2
  • 素数筛法,是一种快速“筛”出2~n之间所有素数的方法。朴素的筛法叫埃氏筛(the Sieve ofEratosth...
    Pecco阅读 524评论 0赞 0
  • 问题提出 设计一个函数将指定范围(比如[1,10000])中的所有素数标记出来,利用arr[10001],如果i是...
    小超chao阅读 388评论 0赞 0
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 131,539评论 2赞 7
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 9,382评论 0赞 4

友情链接更多精彩内容