素数筛 模板

 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\n",L,U,ans1,ans2);
49     }
50     return 0;
51 }
Here

 

posted @ 2014-08-19 18:25  如夜_YanBaoC  阅读(858)  评论(0编辑  收藏  举报