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 }