关于素数筛我们介绍常用的两种素数筛:
普通筛法求素数:复杂度为O(nloglogn)
1 const int maxn = 100000; 2 bool vis[maxn]; 3 memset(vis, false, sizeof(vis)); 4 vis[1] = true; 5 for(int i = 2; i < maxn; ++i) if(!vis[i]){ 6 for(int j = 2*i; j < maxn; j += i) 7 vis[j] = true; 8 } 9 //对于一个数n,若vis[n] == false 则n为素数,否则为合数
欧拉筛(线性筛):复杂度为O(n)
1 const int maxn = 100000; 2 int primer[maxn], n = 0; 3 bool vis[maxn]; 4 memset(vis, false, sizeof(vis)); 5 vis[1] = true; 6 for(int i = 2; i < maxn; ++i) { 7 if(!vis[i]) { 8 primer[n++] = i; 9 } 10 for(int j = 0; j < n; ++j) { 11 if(i * primer[j] >= maxn) { 12 break; 13 } 14 vis[i*primer[j]] = true; 15 if(i % primer[j] == 0) { 16 break; 17 } 18 } 19 }
上面这个算法保证了每个合数只会被它的最小质因子给筛去,所以算法复杂度就是O(n)