zoukankan      html  css  js  c++  java
  • 两大速筛素数以及大区间素数快速统计

    文中有解释:

    #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;
    }
  • 相关阅读:
    Dockerfile
    最近遇到的jsfl开发问题总结
    【Distributed】大型网站高并发和高可用
    【Distributed】CDN
    【Distributed】限流技巧
    【Java并发】锁机制
    【Java并发】线程通信
    【Java并发】线程安全和内存模型
    【Java并发】基础
    【Redis】基本数据类型及命令操作(超详细)
  • 原文地址:https://www.cnblogs.com/maxv/p/10839165.html
Copyright © 2011-2022 走看看