0
点赞
收藏
分享

微信扫一扫

素数筛法 模板

素数筛法 模板_算法模板

素数筛法 模板_算法模板_02

 

为什么只遍历到sqrt(n)就够了?

反证法:
假设只遍历2~sqrt(n)不能把所有非素数置为false,即遍历完了2~sqrt(n)后,在sqrt(n)~n范围内仍有一个非素数k,但isprime[k]=true。

证: k在sqrt(k)之前一定有一个素数因子(任何非素数都可以拆成素数的乘积,所以k至少有一个素数因子),sqrt(k)肯定小于sqrt(n),所以sqrt(n)之前一定有一个k的素数因子y,那么根据代码中的算法,i=y的时候,k肯定会被置为非素数,即此时isprime[k]就会被置为false,原假设不成立。
因此只需遍历2~sqrt(n)即可。

 

 

 此方法时间复杂度为O(n*loglogn),空间复杂度为O(n)

 

1 #include <iostream>
2 #include <cmath>
3
4 using namespace std;
5
6 #define MAXN 10000
7 int prime[MAXN+10]; // 保存筛得的素数
8 int primeSize; // 保存素数的个数
9 bool mark[MAXN+10]; // 若mark[i]为true,表示i被标记为素数
10
11 void init()
12 {
13 for(int i = 2; i <= MAXN; ++i)
14 mark[i] = true; // 初始化,所有数字均被标记为素数
15 primeSize = 0;
16 int m = sqrt(MAXN+1); // sqrt函数比较耗时,所以这里把它提到循环外面
17 for(int i = 2; i <= m; ++i)
18 {
19 if(mark[i] == true)
20 {
21 prime[primeSize++] = i;
22 for(int j = i*i; j <= MAXN; j += i)
23 mark[j] = false; // 该数的所有倍数都不是素数
24 }
25 }
26 }
27

 


举报

相关推荐

0 条评论