欧拉筛详解(代码,证明过程以及时间复杂度分析)

1.欧拉筛的作用

欧拉筛:可以在线性的时间复杂度内,从1~n之间的素数的集合,并且在操作过程中可以记录素数数组,为以后判断是否是素数而加快效率

和大部分的筛法一样,通过将质数的倍数标记为合数来不断筛选质数的一种方法,欧拉筛的大致思路也是这样,不够欧拉筛能实现O(n)时间复杂度的必然有他的过人之处

2.欧拉筛的代码

int pri[200005];//素数集合 
int vis[200005];//判断是否是素数
int cnt=0;//统计素数数量 
void ini()
{
	vis[1]=1;
	for(int i=2;i<=200000;i++)
	{
		if(vis[i]==0)
		{
			cnt++;
			pri[cnt]=i;
		}
		for(int j=1;j<=cnt&&i*pri[j]<=200000;j++)
		{
			vis[i*pri[j]]=1;
			if(i%pri[j]==0)
			break;
		}
	} 
}

思路:我们在去筛选的时候,所有位置上的标记都为0,表示所有数都为质数,但是我们知道1,不是质数,所以要给1特判,然后从2到n,如果是0,就加入到素数数组pri里面,然后就是用当前i去寻找质数倍,然后不断将这些倍数标为合数,如果i%pri[j]==0,那就直接结束循环就可以,这是保证算法为线性的关键

3.正确性的验证

我们可以假设一下,a=p*b;

p表示a的最小质因数

我们同理可以知道b小于a,那么b一定在a之前做出了判断,我们在之前就应删掉b的所有倍数,因为p为a的最小质因数,那么b的最小质因数也一定大于等于p(为什么呢?假如我们的b的最小质因数为q,并且q<p,因为a为b的倍数,a也应为q的倍数,所以q才是a的最小质因数,与条件违背,所以不符)

这样就保证了,在a被删掉之前,b一定不会结束删除他的合数,及时b的最小质因数也为p,也同样能够将a删除

4.时间复杂度的证明 

我们此时需要验证一下如何判断a只会删除一次

我们可以假设a=p*b;p为最小质因数

假设p为b的最小质因数,我们由上述3可知,a一定会被b删掉一次,那么是否还能被另一个数c删除一次呢

我们继续假设a=q*c

假设c<b,那么q>p,这就说明p为c的最小质因数(为什么呢?因为a=q*c=p*b,因为p,q都为质数,那么只有c能整除p,那么按理来说在质数轮到p的时候就结束了,根本轮不到q),因此c不可能小于b 

假设c>b.那么q<p,不满足题目中的条件,p为最小质因数

因此a最多只能删除1次,每个数只处理一次,时间复杂度为O(n)得证

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值