• 素数筛 模板


     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 int prim[3000000]={2,3,5};
     8 //素数是分为基本素数{2,3}、阳素数{6N+1,N>=1}形式的、阴素数{6N-1,N>=1}形式的
     9 //为了代码的好写,在这里这样写的 :
    10 //数除了{2,3,5}为素数,其他的数可以写成6N,6N+1,6N+2,6N+3,6N+4,6N+5  N>=1 可以表示全部的数
    11 //6N,6N+2,6N+4都为偶数,不是素数,6N+3 == 3(2N+1) 不是素数,那么就只筛6N+1和6N+5就可以了
    12 int main()
    13 {
    14     int i, j, flag;
    15     int gcd = 2;
    16     int k = 3;
    17 
    18     for(i=7;i<=20000000;i+=gcd)
    19     {
    20         gcd = 6-gcd;//6N+1和6N+5的变换。
    21         flag = 1;
    22         for(j=0;prim[j]*prim[j]<=i;j++)//判断一个数是否为素数,只需判断这个数在2--sqrt(x)范围即可。
    23             if(i%prim[j] == 0){//因为一个开根号比乘法是要慢的,所以用乘法速度更快。
    24                 flag = 0;
    25                 break;
    26             }
    27         if(flag)//若这个数没有被其他素数整除 说明为素数。
    28             prim[k++] = i;
    29     }
    30     for(i=0;i<k;i++)
    31         printf("%d  ",prim[i]);
    32     return 0;
    33 }

    以上筛法为一位浙江工业大学的老学长的解题报告中给出的,在此引用,但是不知道他老人家的名字,万分惭愧。在此谢谢。

    上面筛法为欧拉筛法的一种优化。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 int hash[2000003];
     8 int prim[500000];
     9 //此为埃氏筛法,是很朴素的一种筛法,O(nlogn)的时间复杂度,可以应付大部分的素数筛,而且代码很短。
    10 int main()
    11 {
    12     int i, j, k = 0;
    13 
    14     memset(hash,0,sizeof(hash));
    15     for(i=2;i<=2000000;i++)
    16     {
    17         if( !hash[i]){
    18             prim[k++] = i;
    19             for(j=2*i;j<=2000000;j+=i)
    20                 hash[j] = 1;
    21         }
    22     }
    23     for(i=0;i<k;i++)
    24         printf("%d ",prim[i]);
    25     return 0;
    26 }

    http://poj.org/problem?id=3511

    附上一道练习题。

    题解代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #define ll long long
     5 
     6 using namespace std;
     7 
     8 int prim[200000]={2,3,5};
     9 int k =3;
    10 
    11 void is_prim()
    12 {
    13     int i, j;
    14     int flag, step = 2;
    15 
    16     for(i=7;i<=1000000;i+=step)
    17     {
    18         step = 6-step;
    19         flag = 1;
    20         for(j=0;prim[j]*prim[j]<=i;j++)
    21             if(i%prim[j] == 0){
    22                 flag = 0;
    23                 break;
    24             }
    25         if(flag)
    26             prim[k++] = i;
    27     }
    28 }
    29 
    30 int main()
    31 {
    32     int L, U;
    33     int i, ans1, ans2;
    34 
    35     is_prim();
    36     while(scanf("%d %d",&L,&U),L!=-1||U!=-1){
    37         ans1 = ans2 = 0;
    38         for(i=0;i<k;i++)
    39         {
    40             if(prim[i]>U)
    41                 break;
    42             if(prim[i]>=L && prim[i]<=U){
    43                 ans1++;
    44                 if((prim[i]-1)%4 == 0 || prim[i] == 2)
    45                     ans2++;
    46             }
    47         }
    48         printf("%d %d %d %d
    ",L,U,ans1,ans2);
    49     }
    50     return 0;
    51 }
    Here


    作者:blueppo
    出处:http://www.cnblogs.com/Yan-C/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Win10开启自带虚拟机
    C# NPOI Word 内容读写
    纯自绘实现的winform下卡片列表
    一个宽带问题
    windows两个命令
    Windows IP 安全策略
    vue自学入门-9 @click后直接跟alert报错
    企业微信创建自建应用-2(手机端)
    企业微信创建自建应用-1(管理端)
    Ngnix实践
  • 原文地址:https://www.cnblogs.com/Yan-C/p/3905680.html
Copyright © 2020-2023  润新知