算法学习-埃氏筛和欧拉筛

两种筛法求正整数N(N>=2)以内的所有素数

  • 为什么要用筛法?
    如果暴力枚举,对于每一个正整数n,我们都要从2尝试到n-1对n进行除法,如果只有一个正整数n,那是相当轻松的,但如果得出一个大范围内所有的素数,那枚举注定效率低下。于是筛法应运而生(大概)。
  • 什么是筛法求素数?
    与其一个一个地找素数,不如先排除所有非素数,也就是合数以及 0,1

接下来先介绍最简单的埃氏筛

埃氏筛

1.知识储备
任何一个大于1的自然数都能被唯一分解有限个质数的乘积,如\(\ X=P1^{a1}+P2^{a2}+······+Pn^{an}\)其中\(P\)为质数,\(a\)为指数.
2.原理

  • 要想筛选出素数,我们得先筛选出合数,也就是先把合数标记上:
    对于N范围内的所有正整数,①若为合数,则其必可以表示为比起小的两个或多个素数的乘积,反过来说,②n内的所有素数,必可以通过几几相乘来表示n范围内的所有合数,进一步说,③对n内的每个素数m,对其进行2~i的乘法( m*i 恰好小于n),必能表示成n内的所有合数。仔细想想②和③的结果是等价的。
    这样,通过③我们就能找出n内的所有合数了并将其标记了。
  • 那要怎么标记?
    我们可以通过使用bool型数组,如 bool arr[n+5]={1,1} 来标记合数。arr[i]=0 表示整数i未被标记,arr[i]=1表示整数 i 被标记为合数。其中前两个 1 是预先给 0 ,1 标记为非素数。
    上代码
int n=0,j=0,i=0,prime[10000]={0};
bool arr[100000]={1,1};
    
cin>>n;

for (i=2,j=2;i<=n;++i,j=2)
    if (arr[i]==0)//前几位总是质数,自然也没标记
    {   
        prime[t]=i;  //prime用于存素数
        ++t;
        while (i*j<=n) 
        {
            arr[i*j]=1;
            ++j;
        }
    }

这样就把n内所有素数存入数组 prime 了。
当然也可以简化一下:

for (i=2,j=2;i<=n;++i,j=2)
        if (arr[i]==0) 
            {
                prime[t++]=i;
                while (i*j<=n) arr[i*j++]=1;
            }

当然还可以进一步优化埃氏筛
我们知道,每次求整数i*j的时候,j都是从二开始,这样肯定会造成不少重复,如" i=2,j=3 "与" i=3,j=2 "。所以我们把每次运算前,令j=i,来减少这些重复:

for (i=2,j=2;i<=n;++i,j=i)//此处修改
        if (arr[i]==0) 
            {
                prime[t++]=i;
                while (i*j<=n) arr[i*j++]=1;
            }

(不过这样不会爆int吗????)

以上便是埃氏筛的实现。

欧拉筛

哪怕另j=i,我们也无法避免重复,例如"i=2,j=6"和"i=3,j=4"时,这两者的j都是大于i的,但还是存在着对 arr[12] 进行重复标记 1 的情况。而欧拉筛可以完美的解决这些问题,在n足够大时,欧拉筛的速度可以是埃氏筛的 3~4 倍。(所以DIO在埃及被阿强欧拉了

埃氏筛与欧式筛的基本理念相同,但实现原理不同。代码如下:

bool isp[MAXN];
int p[MAXN];

void euler(int n){
    int cnt=0;
    for(int i=2;i<=n;++i){
        if(!isp[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&i*p[j]<=n;++j){
            isp[p[j]*i]=1;
            if(i%p[j]==0) break;
        }
    }
}

这东西比较抽象。

如果要理解,最好的办法还是自己从 i=2 开始一步一步尝试为好。

讲一下自己理解的特点:

  • 本身代码的特点实现了对于 arr[j]*i ,总有 i>=j
  • 最后 if (i%arr[j]==0) break; 防止了i>=j 时有的重复标记

没了。

学习自:诶嘿
这位dalao讲得挺好的,可以在上面找到更详细的欧拉筛也就是线性筛的解释。

posted @ 2020-11-05 02:02  七铭的魔法师  阅读(466)  评论(0编辑  收藏  举报