质数线性筛复杂度证明

线性筛是一种 \(O(n)\) 筛出 \(1\sim n\) 中的质数的算法。

for (int i = 2; i <= x; ++i)
{
	if (is_prime[i] == 0)
		prime[++prime_cnt] = i;
	for (int j = 1; j <= prime_cnt && prime[j] * i <= x; ++j)
	{
		is_prime[i * prime[j]] = 1;
		if (i % prime[j] == 0) break;
	}
}

其中

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

是关键的一句

证明:每一个合数只会被最小的质因数筛出

设合数 \(k\) 的最小质因数是 \(p_k\)
先证明合数 \(k\) 一定会被筛到。
\(i\) 枚举到 \(\dfrac{k}{p_k}\) 时,因为 \(p_k\)\(k\) 的最小的质因数,所以 \(\dfrac{k}{p_k}\) 的质因数里一定没有小于 \(p_k\) 的质因数,在 \(p_k\) 之前也就不会有满足 \(\dfrac{k}{p_k} \% p' == 0\)\(p'\) 了。
再证明合数 \(k\) 只会被筛一次。
假设 \(k\) 还存在另一个质因数 \(p'\not= p_k\),使得 \(k\) 会被 \(p'\) 筛掉。
考虑到 \(\dfrac{k}{p'}\) 一定是含有 \(p_k\) 这个质因数的,因为 \(\gcd(p_k, p') = 1\)
所以当 \(prime[j]\) 枚举到 \(p_k\) 时,\(p'\) 一定没有被枚举到,而且 \(\dfrac{k}{p'} \% p_k == 0\) 是成立的,所以此时内层 for 循环一定会被 break 掉。
所以不会枚举到 \(p'\),假设自然也就不成立了。

posted @ 2026-03-19 12:51  SigmaToT  阅读(4)  评论(0)    收藏  举报