Book--Era筛法与Euler筛法

2015-02-09 08:49:30

小结:无意间听杰哥说起欧拉素数筛法,今天把它和Era..筛法做了个比较。(时间已经算上memset耗时)

  (耗时单位:秒)

  欧拉筛法小结:欧拉筛法基于的是每个合数必定有其最小素因子,所以让每个合数只被这个最小素因子筛一次(Era筛会重复筛)

        (这样还能顺便记录每个数的最小素因子)所以时间是线性的。关键是在 if (i % prime[j] == 0) break; 这句。

          如果当前的 i 整除 prime[j],那么不妨将 i 表示为 k*prime[j],如果不 break,那么 k*prime[j]*prime[j+1] 将被筛掉,但是

          这个数显然不是被最小素因子筛掉的,如果 break 掉,这个数会在 i 增大到 k*prime[j+1] 后被 prime[j] 筛掉。

  数据规模:

  (1)10^6:

    Eratosthenes time : 0.0325
    Euler time : 0.0117

  (2) 10^7:       

    Eratosthenes time : 0.2762
    Euler time : 0.1138

  (3)10^8:

    Eratosthenes time : 3.2372
    Euler time : 1.1317 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <ctime>
10 #include <queue>
11 #include <string>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 
16 #define MEM(a,b) memset(a,b,sizeof(a))
17 #define REP(i,n) for(int i=1;i<=(n);++i)
18 #define REV(i,n) for(int i=(n);i>=1;--i)
19 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
20 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
21 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
22 #define MP(a,b) make_pair(a,b)
23 
24 typedef long long ll;
25 typedef pair<int,int> pii;
26 const int INF = (1 << 30) - 1;
27 
28 bool check[1000000005];
29 int N,prime[100000005];
30 
31 int main(){
32     clock_t st,ed;
33     scanf("%d",&N);
34     st = clock();
35     memset(check,false,sizeof(check));
36     int tot = 0;
37     for(int i = 2; i <= N; ++i){
38         if(!check[i]){
39             prime[tot++] = i;
40             for(int j = i * 2; j <= N; j += i)
41                 check[j] = true;
42         }
43     }
44     ed = clock();
45     double dura = (double)(ed - st) / CLOCKS_PER_SEC;
46     printf("Eratosthenes time : %.4f\n",dura);
47 
48     st = clock();
49     memset(check,false,sizeof(check));
50     tot = 0;
51     for(int i = 2; i <= N; ++i){
52         if(!check[i]) prime[tot++] = i;
53         for(int j = 0; j < tot; ++j){
54             if(i * prime[j] > N) break;
55             check[i * prime[j]] = true;
56             if(i % prime[j] == 0) break;
57         }
58     }
59     ed = clock();
60     dura = (double)(ed - st) / CLOCKS_PER_SEC;
61     printf("Euler time : %.4f\n",dura);
62 
63     return 0;
64 }

 

posted @ 2015-02-08 20:58  Naturain  阅读(325)  评论(0编辑  收藏  举报