两大速筛素数以及大区间素数快速统计

文中有解释:

#include<iostream>
#include<cstring >
#include<cstdio>
#include<cmath>
#define maxn 1000001
#define maxx 100005
#define mem(a,b) memset(a,b,sizeof(a));
using namespace std;
int pri[maxn],book[maxn],n,cnt;
int sum(int a[])
{
    int num=0;
    for(int i=2; i<=maxn; i++)
        if(a[i])
            num++;
    return num;
}
int main()
{
    /*
    倍筛法(低能)
    for( int i=2; i*i<=maxn; i++)
        for(int j=2; j*i<=maxn; j++)
            prim[j]=0;
    */
    /* 埃式筛法 */
    mem(pri,1);
    pri[1]=0;
    pri[0]=0;
    /*如果i是素数则删除他的倍数直到大于上限
    埃式筛法相对于倍筛法来说
    避免了一部分重复*/
    for (int i=2; i*i<maxn; i++)
        if(pri[i])
            for(int j=i+i; j<=maxn; j+=i)
                pri[j]=0;
    cout<<sum(pri)<<endl<<endl;
    /* 欧拉筛法 */
    mem(book,1);
    book[1]=0;
    book[0]=0;
    cnt=0;
    /*欧拉筛法*/
    /*欧拉筛法的特点的是用最小
    的质因数去筛除避免了质倍数的重复*/
    for (int i=2; i<=maxn; i++)
    {
        if(book[i])
        {
            pri[cnt++]=i;
        }
        for(int j=0; j<cnt&&pri[j]*i<=maxn; j++)
        {
            book[pri[j]*i]=0;
            if(i%pri[j]==0)
                break;
        }
    }
    cout<<sum(book)<<endl<<endl;
    /* 大区间筛素数(10W_1S) */
    /*  据说用到了数组偏移不是很明白 
    就感觉像是映射一样前一部分数组对
    后面的都有一个相应的影响成素数*/
    while('a')
    {
        bool prim[maxx],primm[maxx];
        mem(prim,1);
        mem(primm,1);
        prim[1]=0;
        long long f,l;
        cin>>f>>l;
        for(long long  i=2; i*i<=l; i++)
            if(prim[i])
            {
                for(long long j=i+i; j*j<=l; j+=i)
                    prim[i]=0;
    //这里的大区间内的元素大小(f+i-1)/i
    //至少是i的二倍, 
                for(int j=max(2LL,(f+i-1)/i)*i; j<=l; j+=i)
                    primm[j-f]=0;
            }
        int ssum=0;
        for(int i=0; i<=l-f; i++)
            if(primm[i])
                ssum++;
if(f==1)
ssum--;
        cout<<ssum<<endl;
    }
    return 0;
}

 

posted @ 2019-05-09 16:19  MaxVen  阅读(434)  评论(0编辑  收藏  举报