新征程2.21 数论(二) 欧拉筛

欧拉筛

笔者正在备考,所以话不多说,直接上代码.

埃氏筛
void work()
{
	for(int i=2;i<=n;++i)
	{
		if(!vis[i])
		{
		zhi[++tot]=i;
		for(int j=2*i;j<=n;j+=i)vis[j]=1;
	    }
	}
}

这部分代码是欧拉筛的核心部分,它的作用是将质数 i 的倍数标记为非质数。具体来说,对于每个质数 i,从它的 2 倍开始,每次加上 i,标记这些数为非质数。

这样做的原因是,一个数如果是质数的倍数,那么它一定有更小的质因数。通过这个过程,我们可以筛选出所有质数.

欧拉筛
void work()
{
	for(int i=2;i<=n;++i)
	{
		if(!vis[i])zhi[++tot]=i;
		for(int j=1;j<=tot && i*zhi[j]<=n;++j)
	    {
	    	vis[zhi[j]*i]=1;
	    	if(i%zhi[j]==0)break;
		}
	}
}

这段代码实现的是改进版的欧拉筛算法。在这个算法中,我们首先遍历每个数 i,如果它是质数,则将其添加到质数数组 zhi 中,并将其倍数标记为非质数。

具体步骤如下:

对于每个数 i,如果它是质数(即没有被标记为非质数),则将其添加到质数数组 zhi 中,并将其倍数标记为非质数。
对于每个质数 zhi[j],将 i 与 zhi[j] 的乘积小于等于 n 的倍数标记为非质数。在这一步中,我们只需要考虑 i 与 zhi[j] 的最小公倍数。
这样的优化能够减少标记的次数,提高算法效率。

posted @ 2024-04-03 16:11  deviancez  阅读(27)  评论(0)    收藏  举报