关于线性筛的一些思考

	memset(is_prime,true,sizeof(is_prime));
	is_prime[0]=is_prime[1]=false;
	for(int i=2;i<=L;i++)
	{
		if(is_prime[i])prime[++cnt]=i;
		for(int j=1;j<=cnt;j++)
		{
			int x=i*prime[j];
			if(x>L)break;
			is_prime[x]=false;
			if(i%prime[j]==0)break; 
		}
	}

这是代码
思考几个问题
1.它是怎样达到O(n)的?
2.为什么i%prime[j]时应该break

首先,达到O(n)的原理————————每一个数只会被唯一的一个数给筛掉
如12会被6筛掉 18会被9筛掉
具体来说,x会被x/d筛掉,d是x的最小的质因数

举例来说

\(12\Longrightarrow6\Longrightarrow3\Longrightarrow1\ \ \ \ \ 3*2*2=12\)
\(18\Longrightarrow9\Longrightarrow3\Longrightarrow1\ \ \ \ \ 3*3*2=18\)
\(180\Longrightarrow90\Longrightarrow45\Longrightarrow15\Longrightarrow5\Longrightarrow1\ \ \ \ \ 5*3*3*2*2=180\)
显然这种划分的方式是唯一的。
为了实现这个功能
便有了

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

这样一句话
比如4的时候,4%2==0,不会再去用4去筛掉12
而是等到6再去用6筛掉12
这是因为发现了4的最小质因数为2,于是就不考虑用更大的质因数了
所以直接break即可

扯完这些基本理论后再来说说怎么用线性筛去筛一些常见的函数

posted @ 2020-08-14 12:30  Creed-qwq  阅读(118)  评论(0编辑  收藏  举报