【总结】数论素数筛之 线筛、埃筛

什么是素数

质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。

一、朴素筛法

根据素数的定义而每个数都进行一次 2 到 ( i − 1 ) 2到(i-1) 2(i1) M o d Mod Mod,如果被整除则不是质数。

代码

bool Prime(int a){
	for(int i=2;i<a;i++){
		if(a%i==0){
			return false;
		}
	}
	return true;
}

优化

这个朴素判断质数中还可以进行优化,使代码的时间复杂度减少很多。
对于每个小于 根 号 i 根号i i的因数,一定有一个大于 根 号 i 根号i i的因数与之配对,使得两个数的积为 i i i,因此,在我们枚举 i i i的因数时,只需要枚举 < = 根 号 i <=根号i <=i的值即可。

代码

bool Prime(int a){
	for(int i=2;i<=sqrt(a);i++){
		if(a%i==0){
			return false;
		}
	}
	return true;
}

好戏真正开始

二、埃氏筛法(简称埃筛)

【总结】数论素数筛之 线筛、埃筛_第1张图片
总而言之,就如下图一般,只要发现 f l a g [ i ] ! = t r u e flag[i]!=true flag[i]!=true,就将它的倍数全部置为 t r u e true true
【总结】数论素数筛之 线筛、埃筛_第2张图片

代码

const int M=10005;
bool flag[M];
int pre[M];//用这个数组来保存1~n的所有质数
void Prime_Ai(int n){
	int k=0;
	for(int i=2;i<=n;i++){
		if(!flag[i]){
			k++;
			pre[k]=i;
			for(int j=i*2;j<n;j+=i){
				flag[j]=true;
			}
		}
	}
}


三、欧拉筛法(简称线筛)

【总结】数论素数筛之 线筛、埃筛_第3张图片
简而言之,就是避免重复置为 t r u e true true而增加时间复杂度,所以有了线筛。
线筛就是利用 p r e [ M ] pre[M] pre[M]里的质数来避免上述问题。

代码

const int M=1005;
bool flag[M];
int pre[M];
void Prime_xian(int n){
	int k=0;
	for(int i=2;i<=n;i++){
		if(!flag[i]){
			pre[++k]=i;
		}
		for(int j=1;j<=k&&pre[j]*i<=n;j++){
			flag[pre[j]*i]=1;
			if(i%pre[j]==0)
				break;
		}
	}
}

你可能感兴趣的:(数论,素数筛)