2 min read 548 words Updated Apr 25, 2026 Created May 03, 2026

筛法

本文不作为教学向文章。

冷静分析:CMD 的博客

线性筛

线性筛是个好东西。一般来说,可以在 $O(n)$ 内处理几乎所有的积性函数。

还可以 $O(n)$ 找出所有的质数……(废话


杜教筛

放在偏序关系 $(\Z, |)$ 中卷积……

如何快速的求 $S(n) = \sum_{i = 1}^n f(i)$

如果能够找到一个函数 $g$

$$\begin{aligned} \sum_{i = 1}^n (f * g)(i) &= \sum_{i = 1}^n \sum_{d | i} f(\frac id) g(d) \\ &= \sum_{d = 1}^{n} g(d) \sum_{i = 1}^{\lfloor \frac nd \rfloor} f(i) \\ &= \sum_{d = 1}^{n} g(d) S(\lfloor \frac nd \rfloor) \\ \end{aligned} $$

那么可以得出:

$$g(1)S(n) = \sum_{i = 1}^n (f * g)(i) - \sum_{d = 2}^n g(d) S(\lfloor \frac nd \rfloor) $$

这样我们就可以通过整除分块快速的求出 $g(1) S(n)$ 了。

当然,需要有很严苛的前提:

  • $f * g$ 的前缀和是可以快速求的。

  • $g$ 的前缀和也是可以快速求的。

  • 这里的快速应该是 $O(1)$,如果是 $O(\log n)$ 估计也没关系。

其时间复杂度大概是在 $O(n^{\frac 23})$ 的,如果不预处理小块的话应该是 $O(n^{\frac 34})$ 的。


例题

  1. 快速求 $\sum_{i = 1}^n \sum_{j = 1}^n \varphi(\gcd(i, j))$

  2. 快速求 $\sum_{i = 1}^n \sum_{j = 1}^n i \cdot j \cdot gcd(i, j)$

例二中有一个很好的东西,点乘。

其定义有:$(f \cdot g)(n) = f(n) \cdot g(n)$

$h$完全积性函数时,有 $(f \cdot h) * (g \cdot h) = (f * g) \cdot h$

这里列出一些基本的组合:

  • $\mu \cdot id_k$

    $((\mu \cdot id_k) * id_k)(n) = \sum_{d | n} \mu(d) d^k (\frac nd)^k = n^{k + 1}\sum_{d | n} \mu(d) = \varepsilon(n)$

  • $\varphi \cdot id_k$

    $(\varphi \cdot id_k) * id_k = I$,推导同上。


Min25 筛

本质是对线性筛的扩展……

为了方便,声明一些符号:

  • $P$ 代表质数集合。

  • $P_i$ 表示第 $i$ 个质数。

  • $minp(i)$ 表示 $i$ 的最小质因数。

还是求 $\sum_{i = 1}^n f(i)$。可以用 Min25 筛需要满足一些条件:

  • $f(i)$ 是一个低阶多项式。

  • $f(p^k)$ 可以快速的求解。

现在考虑把每一阶分别计算。


PN 筛

首先定义 Powerful Number

一个数是 Powerful Number 当其质因数分解中 $n = \prod_{i = 1}^k p_i^{c_i}$$\forall i(c_i > 1)$

由于一个 Powerful Number 可以表示为一个数的平方和一个数的立方,所以 $n$ 以内的 PN 数一共有 $O(\sqrt n)$ 个。

现在假设要求 $F(n) = \sum_{i = 1}^n f(i)$

需要找到函数 $g$ 满足:

  • 为积性函数。

  • 易求前缀和。

  • 在质数 $p$ 处取值与原函数相等:$f(p) = g(p)$

$G(n) = \sum_{i = 1}^n g(n)$

先构造函数 $h$ 满足 $h * g = f$

于是将卷积展开:

$$\begin{aligned} F(n) &= \sum_{i = 1}^n f(i) = \sum_{i = 1}^n \sum_{d | i} h(d) g(\frac id) \\ &= \sum_{d = 1}^{n} \sum_{i = 1}^{\lfloor \frac nd \rfloor} h(d) g(i) \\ &= \sum_{d = 1}^n h(d) \sum_{i = 1}^{\lfloor \frac nd \rfloor} g(i) \\ &= \sum_{d = 1}^n h(d) G(\lfloor \frac nd \rfloor) \end{aligned} $$

怎么可以套数论分块?

由于积性函数相乘任然为积性函数,所以可知 $h(1) = 1$

所以对于质数 $p$,有 $f(p) = g(1)h(p) + g(p)h(1) = h(p) + g(p)$

由于 $f(p) = g(p)$,所以可知 $h(p) = 0$

根据积性函数的性质,可以推导出 $h(n)$ 只在 $n$PN 数的时候才可能不为 $0$

所以原式变为:

$$F(n) = \sum_{\text{d is PN}}^{n} h(d) G(\lfloor \frac nd \rfloor) $$

这样,我们只需要求出 $O(\sqrt n)$$h(d)$ 的取值,以及快速算出 $G(x)$ 的取值即可。

那么我们考虑如何求解 $h(d)$

根据 $f = g * h$

$$f(p^c) = \sum_{i = 0}^c g(p^i)h(p^{c - i}) $$

稍微移项可以得到:

$$g(1)h(p^c) = f(p^c) - \sum_{i = 1}^c g(p^i)h(p^{c - i}) \\ \downarrow \\ h(p^c) = f(p^c) - \sum_{i = 1}^c g(p^i)h(p^{c - i}) $$

于是可以枚举所有的 $p$ 以及 $c$ 求出 $h(p^c)$ 即可。

此时 $p$ 的个数视作 $O(\sqrt n)$,而 $c$ 的界为 $O(\log n)$,有由于是 $\log n$ 转移,所以这部分复杂度为 $O(\sqrt n \log n^2)$,而且这个上界很宽松。

但是如果我们直接推导出 $h(p^c)$ 仅与 $p^c$ 有关的计算公式,那么可能更加优秀,复杂度一般为 $O(\sqrt n \log n)$

所以总的复杂度一般为 $O(\sqrt n + \sqrt n \log n) = O(\sqrt n \log n)$。非常的优秀。

然而根据 CMD 的博客,硬上的复杂度实际上是 $O(\sqrt n / \log n)$……更加优秀了。

不过有些情况下,利用 PN 筛可能需要套一个杜教筛,毕竟我们除了 $h(p^c)$ 还需要求出 $G(x)$ 的前缀和。

此时需要加上杜教筛的复杂度,可以认为是 $O(n^{\frac 23})$ 的。