zoukankan      html  css  js  c++  java
  • 素数筛模板

    求素数是程序设计比赛中经常遇到的问题,最基本的方法是通过素数的定义直接判断,只能被1和它本身整除的数就是素数了。这种方法适合判断单个数是否为素数,当要求一个范围内素数而这个范围又比较大时,这种方法就不太使用了,甚至程序要运行几分钟才能算出结果。

    筛法的思想是去除要求范围内所有的合数,剩下的就是素数了,而任何合数都可以表示为素数的乘积,因此如果已知一个数为素数,则它的倍数都为合数。

    普通的线性筛法:

     1 #include"cstdio"
     2 #include"cstring"
     3 using namespace std;
     4 #define MAX 100000//求MAX范围内的素数
     5 long long su[MAX],cnt;
     6 bool isprime[MAX];
     7 void prime()
     8 {
     9     cnt=1;
    10     memset(isprime,1,sizeof(isprime));//初始化认为所有数都为素数
    11     isprime[0]=isprime[1]=0;//0和1不是素数
    12     for(long long i=2;i<=MAX;i++)
    13     {
    14         if(isprime[i])//保存素数
    15         {
    16             su[cnt++]=i;
    17         }
    18         for(long long j=i*2;j<=MAX;j+=i)//素数的倍数都为合数
    19         {
    20             isprime[j]=0;
    21         }
    22     }
    23 }
    24 int main()
    25 {
    26     prime();
    27     for(long long i=1;i<cnt;i++)
    28         printf("%d  ",su[i]);
    29     return 0;
    30 }

    普通的线性筛法虽然大大缩短了求素数的时间,但是实际上还是做了许多重复运算,比如2*3=6,在素数2的时候筛选了一遍,在素数为3时又筛选了一遍。如果只筛选小于等于素数i的素数与i的乘积,既不会造成重复筛选,又不会遗漏。时间复杂度几乎是线性的。

    优化后的线性筛法:

     1 #include"cstdio"
     2 #include"cstring"
     3 using namespace std;
     4 #define MAX 100000//求MAX范围内的素数
     5 long long su[MAX],cnt;
     6 bool isprime[MAX];
     7 void prime()
     8 {
     9     cnt=1;
    10     memset(isprime,1,sizeof(isprime));//初始化认为所有数都为素数
    11     isprime[0]=isprime[1]=0;//0和1不是素数
    12     for(long long i=2;i<=MAX;i++)
    13     {
    14         if(isprime[i])
    15             su[cnt++]=i;//保存素数i
    16         for(long long j=1;j<cnt&&su[j]*i<MAX;j++)
    17         {
    18             isprime[su[j]*i]=0;//筛掉小于等于i的素数和i的积构成的合数
    19         }
    20     }
    21 }
    22 int main()
    23 {
    24     prime();
    25     for(long long i=1;i<cnt;i++)
    26         printf("%d  ",su[i]);
    27     return 0;
    28 }

    输出的结果是这样的:

    本文转载自:acm基础知识储备

  • 相关阅读:
    移动端页面适配———多方案解析
    折叠面板实现,上传文件进度条,三级联选择器,多级联选择器, 利用layui实现
    php二维数组去重
    php抽奖算法
    JS如何判断json是否为空
    MySQL中GROUP_CONCAT()函数
    ubuntu卸载安装mysql
    ubuntu安装phalcon
    Ubuntu 16.04 设置MySQL远程访问权限
    首次ubuntu给root设置密码
  • 原文地址:https://www.cnblogs.com/lu1nacy/p/10016640.html
Copyright © 2011-2022 走看看