埃式筛法:“埃拉托斯特尼筛法,简称埃氏筛或爱氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数。”
算法复杂度:O(nloglogn),可以看成线性的
模板一(《挑战程序设计竞赛p118》):
//埃式筛法
//求n以内的质数的个数
int p;
int prime[maxn];
bool is_prime[maxn];
int prime(int n)
{
p = 0;
for(int i = 0; i <= n; i++) is_prime[i] = true;
is_prime[0] = is_prime[1] = false;
for (int i = 2; i <= n; ++i){
if (is_prime[i]){
prime[p++] = i;
for (int j = 2*i; j <= n; j += i) is_prime[j] = false;
}
}
return p;
}
模板二:
对于求区间[0,n]内有多少个素数,我们知道:
n以内的合数的质因数一定不会超过n½,所以在一层循环找质因数时,循环条件可以改为:
int i = 2; i*i <= n; i++
而在第二层循环提出质因数倍数时,i,2*i,....,(i-1)*i已经被前面的质因数剔除,因此:
循环可以从i*i开始,循环条件可以改为:
int j = i*i; j <= n; j += i
这样就减小了时间的复杂度
改进模板如下:
//埃式筛法
//求n以内的质数的个数
int p;
int prime[maxn];
bool is_prime[maxn];
int prime(int n)
{
p = 0;
for (int i = 0; i <= n; ++i) is_prime[i] = true;
is_prime[0] = is_prime[1] = false;
for (int i = 2; i*i <= n; ++i)
if (is_prime[i])
for (int j = i*i; j <= n; j += i)
is_prime[j] = false;
for (int i = 0; i <= n; ++i)
if (is_prime[i])
prime[p++] = i;
return p;
}