您的位置:首页 > 其它

素数筛法

2017-10-05 20:26 204 查看

素数筛法

这一次我们一步一步的来了解素数筛法。

O(nlogn)筛法

一般情况下我们可能比较熟悉的就是O(nlogn)的筛法。

for(int i=2;i<=n;i++)
{
if(!vis[i])
{
for(int j=2;j*i<=n;j++)
vis[j*i]=1;
}
}


时间复杂度计算:

n/1+n/2+…+n/n=nlogn

O(nloglogn)筛法

这个筛法与上述筛法唯一的区别就是在内层循环中的起点由2变为了j,这样时间复杂度就变为了O(nloglogn),是增长速度比较慢的一个筛法。

for(int i=2;i<=n;i++)
{
if(!vis[i])
{
for(int j=i;j*i<=n;j++)
vis[j*i]=1;
}
}


O(n)线性筛

int mindiv[],prime[],tot;

for(int i=2;i<=n;i++)
{
if(!mindiv[i]) mindiv[i]=i,prime[tot++]=i;
for(int j=0;prime[j]*i<=n;j++)
{
mindiv[prime[j]*i]=prime[j];
if(prime[j]!=mindiv[i])
break;
}
}


自我感觉这一个比较好理解,其原理是这样的:对于n以内的数,我们从2开始枚举。

if(i%prime[j]==0)

break;

这一步判断是能够把时间复杂度限制到O(N)的保证。

(代码转自Li Zhuohan

void getlist(int n)
{
memset(isprime,1,sizeof(isprime));
isprime[1]=false;
for(int i=2;i<=n;i++)
{
if(isprime[i])prime[++primesize]=i;
for(int j=1;j<=primesize&&i*prime[j]<=listsize;j++)
{
isprime[i*prime[j]]=false;
if(i%prime[j]==0)break;
}
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: