埃氏筛法求给定区间内素数个数

题目原型:
给定整数a,b,请问区间内有多少个素数?
应对策略:
预备知识
埃氏筛法
思想是首先默认所有数都是素数,然后从2开始,对每个数字进行遍
历,如果该数字是素数,那么它的倍数就不是素数,与单独判断每个
数字是不是素数相比,如此可以大大减少判断素数的时间。

int prime[MAX_N];
bool isprime[MAX_N+1];
int shieve(int n)
{
    int cnt=0;//cnt记录素数个数
    for(int i=0;i<=n;i++)
        isprime[i]=true;
    for(int i=2;i*i<=n;i++)
    {
        if(isprime[i])
        {
            prime[p++]=i;
            for(int j=2*i;j<=n;j+=i)
                isprime[j]=false;
        }
    }
    return cnt;
}

进一步~~
对于求出给定区间[a,b]的素数。
1.先筛选好[2,√b]之间的素数,然后在[a,b]内筛去对应的倍数
即可。

typedef long long ll;
bool isprime[MAX_L];//
bool isprime_small[MAX_SQRT_B];
//接下来进行对[a,b)进行筛选,假定若isprime[i-a]=1,则i是素数;即若isprime[0]=1,则a为素数。
ll segment_sieve(ll a,ll b)
{
    for(int i=2;(ll)i*i<b;i++)
        isprime_small[i]=truefor(int i=0;i<b-a;i++)
        isprime[i]=true//首先初始化,依然默认所有都是素数。
    for(int i=2;(ll)i*i<b;i++)
    {
        if(isprime_small[i])
        {
            for(int j=2*i;(ll)j*j<b;j+=i)
                isprime_small[j]=false;
                //首先对[0,√b]进行筛选
                for(ll j=max(2LL,(a+i-1)/i))*i;j<b;j+=i)
            isprime[j-a]=false;
        }
    //备注:2LL是2的长整数形式
    //(a+i-1)>=a;j>=a;
    //显然j从2*i开始,进行素数筛选.
    }
    ll cnt=0;
    for(ll i=0;i<b-a;i++)
    {
        if(isprime[i])
        cnt++;
    }
    return cnt;
}

你可能感兴趣的:(埃氏筛法求给定区间内素数个数)