质数线性筛复杂度证明
线性筛是一种 \(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'\),假设自然也就不成立了。

浙公网安备 33010602011771号