何为线性筛?
即在时间内筛出质数的算法,也被称为欧拉筛
可以同时求出质数表与是否为质数
相信大家都学过埃筛时间复杂度为,这在数据量大的时候是不够看的
它的原理为:枚举质数的倍数
可这样势必会造成重复筛((。﹏。))
为什么欧拉筛可以做到呢?
因为欧拉筛有一行至关重要的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;
}
}
}