详解线性筛质数,新手都能看懂的代码与解析

何为线性筛?

即在O(n)时间内筛出质数的算法,也被称为欧拉筛

可以同时求出质数表与是否为质数

洛谷真题直达

相信大家都学过埃筛时间复杂度为O(nloglogn),这在数据量大的时候是不够看的

它的原理为:枚举质数的倍数

可这样势必会造成重复筛((。﹏。))

为什么欧拉筛可以做到O(n)呢?

因为欧拉筛有一行至关重要的break来节省重复的筛

大致原理为枚举一个大数乘以每一个质数,在大数是质数的倍数时break掉

为什么这样呢?

思考一下,设外层枚举的数为w,内层枚举的质数为p

设d=i*p (p<=i)

每一轮筛都会把d筛掉

那么如果以后有i2%p==0,即i2是p的倍数

所以它在之前已经被筛选过了,不必继续

当然有人会问,那后面的呢?

后面的当然是留给后面的 i 筛啦ヾ(≧▽≦*)o

 下面就放一下代码

注意啦,break语句要放在isprime[d]=0后

不然你这次筛什么

好啦,自认为讲的很详细了,如果不会可以私信问

如果讲的有错误的话,请大佬们指正.

点个赞和关注?

欧拉筛函数代码为:

void get_prime(const int n)
{
	int now_x;
	memset(isprime,1,n);
	isprime[0]=isprime[1]=0;
	for(int i=2;i<n;++i)
	{
		if(isprime[i]){prime[top++]=i;}
		now_x=i<<1;
		for(int e=0;now_x<n && e<top;)
		{
			isprime[now_x]=0;
			if(i%prime[e]==0){break;}
			now_x=prime[++e]*i;
		}
	}
}

题解代码如下:

#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string.h>
using namespace std;
const int N=2e8;
#define lnt long long
int sr,cz,G,p;
char isprime[N];
int prime[N],top;
void get_prime(const int n);
int main()
{
    scanf("%d%d",&p,&G);
    get_prime(p);
    while(G--)
    {
		scanf("%d",&p);--p;
		printf("%d\n",prime[p]);
	}
    
    return 0;
}

void get_prime(const int n)
{
	int now_x;
	memset(isprime,1,n);
	isprime[0]=isprime[1]=0;
	for(int i=2;i<n;++i)
	{
		if(isprime[i]){prime[top++]=i;}
		now_x=i<<1;
		for(int e=0;now_x<n && e<top;)
		{
			isprime[now_x]=0;
			if(i%prime[e]==0){break;}
			now_x=prime[++e]*i;
		}
	}
}

  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值