用筛法求素数的基本原理,是把从1开始的某一范围内的正整数从小到大顺序排列,逐步筛掉非素数留下素数。
1.朴素筛法
时间复杂度
很容易想到从1枚举到n,挨个判断是不是素数;
Code:
bool ifprime(LL x)
{
int i,j;
for(i=2;i*i<=x;i++)
if(x%i==0)
return false;
return true;
}
void Prime()
{
int i,j;
for(i=2;i<=n;i++) {
if(ifprime(i))
pm[++tot]=i;
}
return;
}
2.Eratosthenes筛法
令A为素数,则A*N(N>1;N为自然数)都不是素数。
时间复杂度
Code:
const LL N=1e7+5;
int pm[N];
bool tag[N];
int tot;
void Prime()
{
int i,j;
for(i=2;i<=n;i++) {
if(!tag[i])
pm[++tot]=i;
for(j=2;j<=i;j++) {
if(i*j>n) break;
tag[i*j]=true;
}
}
return;
}
3.线性筛法
在Eratosthenes筛法的基础上,让每个数最多被其最小质因数筛掉一次;
时间复杂度
Code:
void Prime()
{
int i,j;
for(i=2;i<=n;i++) {
if(!tag[i])
pm[++tot]=i;
for(j=1;j<=tot;j++) {
if(i*pm[j]>n) break;
tag[i*pm[j]]=true;
if(i%pm[j]==0)
break;
}
}
return;
}