埃氏筛与线性筛

文章目录

  • 前言
  • 一、埃氏筛
  • 二、线性筛在埃氏筛上的进化
  • 三、算数基本定理与最小质因子
  • 四、线性筛的代码实现
    • 关于 if(i%prime[j]==0) break;
    • 例如


前言

线性筛(欧拉筛)是埃氏筛的进阶版,埃氏筛的复杂度是:O(n*loglogn),而线性筛的复杂度是 O(n),但一般情况下来说埃氏筛就已经足够满足大多OJ的需求。

一、埃氏筛

埃氏筛, 全名埃拉托斯特尼筛法,是一种古老且简单的用来找出一定范围内所有的质数的算法,公元前250年由希腊数学家埃拉托斯特尼提出。
这种算法的主要思想是:一个素数的整数倍一定是合数
代码实现如下:

#include 

using namespace std;

const int n = 1e7+10;//0表示合数,1表示素数
bool x[n];//数组定义在主函数外部,系统自动将其初始化为0
int prime[n];//用来存放素数

int main()
{
	memset(x,1,sizeof(x));//先假设所有数字都是素数
	memset(prime,0,sizeof(prime));//初始化是一个好习惯
	
	x[0]=x[1]=0;int count1=0;//0和1不是素数,count1用来计数
	
	for(int i=2;i<=n;i++)
	{
		if(x[i])//如果i是素数,把他放入prime数组中
		prime[count1++]=i;
		
		if(x[i]==0)
		continue;//如果i已经是合数,就没必要进行下一步了
		
		for(int j=0;j*i<=n;j++)
		x[j*i]=0;//素数的整数倍一定是合数
		
	}
	
	for(int i=0;i<count1;i++)
	cout<<prime[i]<<" "<<endl;
	
	return 0;

}

二、线性筛在埃氏筛上的进化

将前面埃氏筛的代码弄清楚之后,我们可以发现,对于埃氏筛来说,如果要将30这个数标记为合数,会存在重复标记的现象,比如 2 乘15 , 3 乘10 , 5乘6,而这很明显会浪费时间。

以这个为基础,线性筛诞生了。线性筛的思想就是在埃氏筛的基础上,去掉重复标记的部分,使得每一个数只被他的最小质因子标记一次。

三、算数基本定理与最小质因子

算数基本定理
任何一个大于1的自然数 N , 如果N不为素数,那么N可以唯一分解成有限个质数的乘积。

最小质因子
一个合数分解出的有限个素数乘积中,最小的那个素数。

也就是说,每一个非素数,都有他对应的一个最小质因子,而我们只通过这个最小质因子将其标记为素数或者合数,这样就避免了重复标记。

四、线性筛的代码实现

#include 

using namespace std;
const int n= 1e7+10;

bool x[n];
int prime[n];

int main()
{
	memset(x,1,sizeof(x));
	memset(prime,0,sizeof(prime));
	
	x[0]=x[1]=0;int count1=0;
	
	for(int i=2;i<=n;i++)
	{
		if(x[i])
		prime[count1++]=i;
		
		for(int j=0;j<count1&&i*prime[j]<=n;j++)
		{
			x[prime[j]*i]=0;
			
			if(i%prime[j]==0)
			break;//整个线性筛的精髓在于此,下文有解释
		}
	}
	
	for(int i=0;i<count1;i++)
	cout<<prime[i]<<" ";
}

关于 if(i%prime[j]==0) break;

为什么当 i 是prime [j]的整数倍时就break了呢,我们可以回头想想,我们要改进埃氏筛,只通过这个数的最小质因数将数字标记它,那么我们就要加上一句话来判断:即将被筛掉的数是否是通过其最小质因数来筛掉的。

这里有一个结论,如果i是prime[j]这个素数的整数倍,那么意味着prime[j+1]不是prime[j+1]*i的最小质因数

这里给出数学证明:
当i是prime [j]的整数倍时,我们假设i= k* prime[j] ,k为正整数,下一步要筛的是i*prime[j+1] ,将 i 带入表达式,即证明k*prime[j]*prime[j+1]的最小质因子不是prime[j+1], 而由于prime数组是升序排列,所以prime [j] < prime[j+1], 命题得证。

例如

埃氏筛与线性筛_第1张图片
1.作者很菜,不足之处敬请指出
2.听说给我点赞的人后来都加薪了?

你可能感兴趣的:(c++,笔记,c++,素数筛)