莫比乌斯反演与杜教筛——从入门到入土

8 minute read

Published:

本文中 $p$ 是质数。$p^k$ 是质数的幂。

广告

https://github.com/August-Light/NTFuncs

这是一个关于各种数论函数的 Python 库!

前置知识

数论函数

数论函数:定义域为正整数的函数。

  • 对于数论函数 $f$,对于任意 $\gcd(n,m) = 1$,如果有 $f(nm) = f(n)f(m)$,则 $f$ 为积性函数
    • 积性是十分美好的性质。对于积性函数,你只需要考虑 $p^k$ 处的取值,对于其它数只需要分解质因数然后乘起来就好了。
  • 对于数论函数 $f$,对于任意 $n,m$,如果有 $f(nm) = f(n)f(m)$,则 $f$ 为完全积性函数

数论函数的运算

  • $+$,加法:$(f + g)(x) = f(x) + g(x)$。
  • $-$,减法:$(f - g)(x) = f(x) - g(x)$。
  • $\cdot$,点积:$(f \cdot g)(x) = f(x) \times g(x)$。
  • $*$,Dirichlet 卷积:$(f * g)(x) = \sum\limits_{dn}f(d)g(\dfrac n d)$。
    • 这运算看起来很奇怪。后文会详细说明这种运算的性质。

常见的数论函数

这一部分的记号好像每个人都不太一样?

  • $\varepsilon(x) = [x = 1]$。【完全积性函数】
  • $\text{Id}_k(x) = x^k$。【完全积性函数】
    • 特殊地,$\text{Id}_0$ 可以记为 $1$。
    • 特殊地,$\text{Id}_1$ 可以记为 $\text{Id}$。
  • $\varphi(x)$ 为欧拉函数(A000010)。【积性函数】
    • $\varphi(x)$ 为 $[1,x]$ 中与 $x$ 互质的数的个数。
  • $\sigma_k(x) = \sum\limits_{d \mid x} x^k$。【积性函数】
    • 特殊地,$\sigma_0$ 可以记为 $d$。(也记作 $\tau$,较少见)
    • 特殊地,$\sigma_1$ 可以记为 $\sigma$。
  • $\mu(x)$ 为莫比乌斯函数(A008683)。【积性函数】
    • 后文会详细说明。

Dirichlet 卷积

如果一个数论函数 $h$ 与数论函数 $f,g$ 有以下关系:

\[h(n) = \sum\limits_{d|n}f(d)g(\dfrac n d)\]

\[h = f * g\]

Dirichlet 卷积的性质

  • 交换律。
  • 结合律。
  • 有单位元 $\varepsilon$。
  • 每个数论函数 $f$(除了 $f(1) = 0$ 的)都有逆元(即 $f * g = \varepsilon$):
    • $g(n) = \dfrac 1 {f(1)} \left([n = 1] - \sum\limits_{in, i \ne 1} f(i)g\left(\dfrac n i \right)\right)$
    • $f$ 的逆元记作 $f^{-1}$。
  • 与加法的分配律:$(f + g) * h = f * h + g * h$。
  • 与点积的分配律($h$ 为完全积性函数):$(f * g) \cdot h = (f \cdot h) * (g \cdot h)$。
  • 重要:两个积性函数的 Dirichlet 卷积依然是积性函数
  • 重要积性函数的 Dirichlet 逆元依然是积性函数

证明留作练习

$1$ 的逆元:莫比乌斯函数 $\mu$

$1$ 是积性函数,所以它的逆 $\mu$ 也是积性函数。

根据定义,不难推导得到 $\mu(p^k) = \begin{cases} 1 & k=0 \ -1 & k=1 \ 0 & k>1 \end{cases}$。

常见的 Dirichlet 卷积

  • $1 * \mu = \varepsilon$。
  • $\varphi * 1 = \text{Id}$ 即 $\text{Id} * \mu = \varphi$。
    • 证明留做习题。
    • 这一条非常重要。
  • $1 * 1 = d$ 即 $d * \mu = 1$。
  • $\text{Id}_k * 1 = \sigma_k$ 即 $\sigma_k * \mu = \text{Id}_k$。
  • $\lambda * (\mu \cdot \mu) = \varepsilon$。

莫比乌斯反演

例 1:最简单的莫比乌斯反演

[POI2007] ZAP-Queries:求 $\sum\limits_{i=1}^n \sum\limits_{j=1}^m [\gcd(i,j)=1]$。要求 $O(n)$。(挑战:$O(n^{\frac 2 3})$)

推导:不妨设 $n \le m$。

\[\begin{aligned} & \sum\limits_{i=1}^n \sum\limits_{j=1}^m [\gcd(i,j)=1] \\ =& \sum\limits_{i=1}^n \sum\limits_{j=1}^m \sum\limits_{d|\gcd(i,j)} \mu(d) & \mu * 1 = \text{Id} \\ =& \sum\limits_{i=1}^n \sum\limits_{j=1}^m \sum\limits_{d=1}^n [d|i][d|j] \mu(d) \\ =& \sum\limits_{d=1}^n \mu(d) \sum\limits_{i=1}^n \sum\limits_{j=1}^m [d|i][d|j] \\ =& \sum\limits_{d=1}^n \mu(d) \left\lfloor\dfrac nd \right\rfloor \left\lfloor\dfrac md \right\rfloor \end{aligned}\]

线性筛 $\mu$ 时间复杂度 $O(n)$。

杜教筛 $\mu$ 时间复杂度 $O(n^{\frac 2 3})$。

例 2:难一点的莫比乌斯反演

[Luogu P2398] GCD SUM:求 $\sum\limits_{i=1}^n \sum\limits_{j=1}^m \gcd(i,j)$。要求 $O(n)$。(挑战:$O(n^{\frac 2 3})$)

推导:不妨设 $n \le m$。

\[\begin{aligned} & \sum\limits_{i=1}^n \sum\limits_{j=1}^m \gcd(i,j) \\ =& \sum\limits_{d=1}^n d \sum\limits_{i=1}^n \sum\limits_{j=1}^m [\gcd(i,j) = d] \\ =& \sum\limits_{d=1}^n d \sum\limits_{i=1}^{\lfloor \frac n d \rfloor} \sum\limits_{j=1}^{\lfloor \frac m d \rfloor} [\gcd(i,j) = 1] \\ =& \sum\limits_{d=1}^n d \sum\limits_{i=1}^{\lfloor \frac n d \rfloor} \sum\limits_{j=1}^{\lfloor \frac m d \rfloor} \sum\limits_{t=1}^n [t|i][t|j] \mu(t) \\ =& \sum\limits_{d=1}^n d \sum\limits_{t=1}^n \mu(t) \sum\limits_{i=1}^{\lfloor \frac n d \rfloor} \sum\limits_{j=1}^{\lfloor \frac m d \rfloor} [t|i][t|j] \\ =& \sum\limits_{d=1}^n d \sum\limits_{t=1}^n \mu(t) \left\lfloor \dfrac n {dt} \right\rfloor \left\lfloor \dfrac m {dt} \right\rfloor \\ =& \sum\limits_{T=1}^n \left\lfloor \dfrac n T \right\rfloor \left\lfloor \dfrac m T \right\rfloor \sum\limits_{d|T} d \mu(\dfrac T d) & \text{把 } dt \text{ 用 } T \text{代替} \\ =& \sum\limits_{T=1}^n \varphi(T) \left\lfloor \dfrac n T \right\rfloor \left\lfloor \dfrac m T \right\rfloor & \text{Id} * \mu = \varphi\\ \end{aligned}\]

线性筛 $\varphi$ 时间复杂度 $O(n)$。

杜教筛 $\varphi$ 时间复杂度 $O(n^{\frac 2 3})$。

例 3:例 2 的一般化

给定 $A,B,C$,求 $\sum\limits_{i=1}^n \sum\limits_{j=1}^m A_i \times B_j \times C_{\gcd(i,j)}$。要求 $O(n \log n)$。(挑战:$O(n \log \log n)$)

推导:膜拜 ZAK。

\[\begin{aligned} & \sum\limits_{i=1}^n \sum\limits_{j=1}^m A_i B_j C_{\gcd(i,j)} \\ =& \sum\limits_{d=1}^n C_d \sum\limits_{i=1}^n \sum\limits_{j=1}^m A_i B_j [\gcd(i,j) = d] \\ =& \sum\limits_{d=1}^n C_d \sum\limits_{i=1}^{\lfloor \frac n d \rfloor} \sum\limits_{j=1}^{\lfloor \frac m d \rfloor} A_{id} B_{jd} [\gcd(i,j) = 1] \\ =& \sum\limits_{d=1}^n C_d \sum\limits_{i=1}^{\lfloor \frac n d \rfloor} \sum\limits_{j=1}^{\lfloor \frac m d \rfloor} A_{id} B_{jd} \sum\limits_{t=1}^n [t|i][t|j] \mu(t) \\ =& \sum\limits_{d=1}^n C_d \sum\limits_{t=1}^n \mu(t) \sum\limits_{i=1}^{\lfloor \frac n d \rfloor} \sum\limits_{j=1}^{\lfloor \frac m d \rfloor} A_{id} B_{jd} [t|i][t|j] \\ =& \sum\limits_{d=1}^n C_d \sum\limits_{t=1}^n \mu(t) \sum\limits_{i=1}^{\lfloor \frac n {dt} \rfloor} \sum\limits_{j=1}^{\lfloor \frac m {dt} \rfloor} A_{idt} B_{jdt} \\ =& \sum\limits_{T=1}^n \left(\sum\limits_{i=1}^{\lfloor \frac n T \rfloor} A_{iT}\right) \left(\sum\limits_{j=1}^{\lfloor \frac m T \rfloor} B_{jT}\right) \left(\sum\limits_{d|T} C_d \mu(\dfrac T d)\right) \\ =& \sum\limits_{T=1}^n \left(\sum\limits_{i=1}^{\lfloor \frac n T \rfloor} A_{iT}\right) \left(\sum\limits_{j=1}^{\lfloor \frac m T \rfloor} B_{jT}\right) (C * \mu)(T) \\ \end{aligned}\]

直接做是调和级数的 $O(n \log n)$。

Dirichlet 后缀和 + Dirichlet 差分可以做到 $O(n \log \log n)$。

例 3.5:Dirichlet 四变换

[Luogu P5495]【模板】Dirichlet 前缀和:已知 $f$,对于 $1$ 到 $n$ 的所有 $i$,求出 $g_i = \sum\limits_{di} f_d$。要求 $O(n \log \log n)$。

先看代码:

// primes 为一个 vector,需要线性筛预处理
for (auto j : primes)
    for (int i = 1; i * j <= n; i++)
        f[i * j] += f[i];

理解 1:高维空间

每一个数可以看成一个高维空间中的点。具体来说,$n = \prod p_i^{k_i}$,则 $n$ 就对应 $(k_1, k_2, k_3, \cdots)$ 这个点。

$ab$ 就意味着每一维 $a$ 的坐标都小于等于 $b$ 的坐标。

经过上述转化,那么本题就变为了高维前缀和问题。普通高维前缀和有显而易见的 $O(3^n)$ 优化到 $O(n2^n)$ 的做法,此题也一样,朴素的 $O(n \log n)$ 可以被优化到 $O(n \log \log n)$。

这个理解可以很容易拓展到 Dirichlet 四变换:

  • Dirichlet 前缀和(高维前缀和)
    • $g_i = \sum\limits_{di} f_d$
  • Dirichlet 前缀差分(前一个的逆运算)
  • Dirichlet 后缀和(高维后缀和)
    • $g_i = \sum\limits_{id} f_d$
  • Dirichlet 后缀差分(前一个的逆运算)

理解 2:拆开积性函数

显而易见的,$g = f * 1$。

定义 $F_p(x) = \begin{cases} F(x) & x=p^k \ 0 & \text{otherwise} \end{cases}$。(此题 $F = 1$)

不难发现,$F = F_{p_1} * F_{p_2} * \cdots$($p_i$ 为第 $i$ 个质数)。

而把一个函数卷上 $F_p$ 是简单的,只需要 $O\left(\dfrac n p\right)$ 时间。总复杂度 $O(n \log \log n)$。

推广:Dirichlet 前缀差分即为 $g = f * \mu$,可以用一样的方法。事实上,卷任何积性函数都可以。

例 4:乘积与数论函数

[SDOI2015] 约数个数和:求 $\sum\limits_{i=1}^n \sum\limits_{j=1}^m d(ij)$。要求 $O(n) - O(\sqrt n)$。

有以下四个常见的函数乘积结论:

  • $\mu(ij) = [i \perp j] \mu(i) \mu(j)$
  • $d(ij) = \sum\limits_{xi} \sum\limits_{yj} [x \perp y]$
  • $\varphi(ij) = \dfrac {\varphi(i) \varphi(j) \gcd(i,j)} {\gcd(\varphi(i,j))}$
  • $\sigma_k(ij) = \sum\limits_{xi} \sum\limits_{yj} [x \perp y] (\dfrac {xj} y)^k$

(如何发现这些结论呢?注意到这些都是积性函数,所以只考虑 $p^k$,即令 $i=p^a, j=p^b$,然后瞎推式子)

在知道了结论之后,推导式子也就不难了,留作练习。

例 5:积性函数乘积求和

给定积性函数 $S$,求 $\sum\limits_{i=1}^n \sum\limits_{j=1}^m S(i \times j)$。要求 $O(n \log n \log \log n)$。

膜拜 ZAK。

枚举 $g = \gcd(i,j)$。推导:

\[\begin{aligned} & \sum\limits_{i=1}^n \sum\limits_{j=1}^m S(i \times j) \\ =& \sum\limits_{g=1}^n \sum\limits_{i=1}^{\lfloor \frac n g \rfloor} \sum\limits_{j=1}^{\lfloor \frac m g \rfloor} [i \perp j] S(g^2 ij) \end{aligned}\]

引理:对于积性函数 $S$ 与自然数 $c$,对于任意 $i \perp j$,有:

\[S(c \times i) S(c \times j) = S(c \times i \times j) S(c)\]

证明:只考虑质数幂处,$i,j$ 互质,必有一个为 $1$,显然左右两侧相等。

构造一个函数 $H_g(x) = \dfrac {S(g^2 x)} {S(g^2)}$,根据上文引理可得 $H_g$ 是积性函数。

继续推导:

\[\begin{aligned} & \sum\limits_{g=1}^n \sum\limits_{i=1}^{\lfloor \frac n g \rfloor} \sum\limits_{j=1}^{\lfloor \frac m g \rfloor} [i \perp j] S(g^2 ij) \\ =& \sum\limits_{g=1}^n \sum\limits_{i=1}^{\lfloor \frac n g \rfloor} \sum\limits_{j=1}^{\lfloor \frac m g \rfloor} [i \perp j] S(g^2) H_g(ij) \\ =& \sum\limits_{g=1}^n S(g^2) \sum\limits_{i=1}^{\lfloor \frac n g \rfloor} \sum\limits_{j=1}^{\lfloor \frac m g \rfloor} [i \perp j] H_g(i) H_g(j) \end{aligned}\]

套进例 3 式子($A = H_g$,$B = H_g$,$C = \varepsilon$)。

时间复杂度 $O(\sum\limits_{g=1}^n \dfrac n g \log \log \dfrac n g) = O(n \log n \log \log n)$。

杜教筛

定义 $S_f(n) = \sum\limits_{i=1}^n f(i)$。

基本和组(也叫块筛):对于数论函数 $f$ 与正整数 $n$,$S_f\left(\left\lfloor \dfrac n i \right\rfloor\right)$ 的一系列值被称为基本和组。

  • 就是数论分块时会用到的那些值。
  • 显然 $S_f\left(\left\lfloor \dfrac n i \right\rfloor\right)$ 的不同值只有 $O(\sqrt n)$ 个。

杜教筛用于在低于线性的时间内求一个函数的前缀和的基本和组。

前提条件:对于要求基本和组的函数 $f$,能够构造一个函数 $g$,使得 $g$ 与 $f * g$ 的基本和组都能在 $O(n^{\frac 2 3})$ 之内求出。

\[\begin{aligned} & \sum\limits_{i=1}^n (f * g)(i) \\ =& \sum\limits_{i=1}^n \sum\limits_{xy=i} f(x) g(y) \\ =& \sum\limits_{y=1}^n g(y) \sum\limits_{xy \le n} f(x) \\ =& \sum\limits_{y=1}^n g(y) S_f\left(\left\lfloor \dfrac n y \right\rfloor\right) \end{aligned}\]

(事实上,根据这个式子,可以在 $O(n^{\frac 2 3})$ 时间内根据 $f,g$ 的基本和组求出 $f * g$ 的基本和组,与杜教筛相反)

所以:

\[S_f(n) = \dfrac 1 {g(1)} \left(S_{f*g}(n) - \sum\limits_{i=2}^n g(i) S_f\left(\left\lfloor \dfrac n i \right\rfloor\right)\right)\]

数论分块 + 记忆化。(有定理:$\left\lfloor \dfrac {\left\lfloor \dfrac a b \right\rfloor} c \right\rfloor = \left\lfloor \dfrac a {bc} \right\rfloor$,所以确实会求出整个基本和组)

用微积分知识可得时间复杂度为 $O(n^{\frac 3 4})$。

预先线性筛处理 $S_f$ 在前 $O(n^{\frac 2 3})$ 的值,其他值用上文办法处理,可以用微积分知识证明时间复杂度 $O(n^{\frac 2 3})$。

关于记忆化:

  • unordered_map 最简单,并且多测的话还能重复利用,有助于卡常。
  • 也可以以 $\lfloor \dfrac n x \rfloor$ 作为标识存储 $S_f(x)$ 的值。不会出现重复。但是多测要记得清空。

杜教筛例题

例 1:模板

[Luogu P4213]【模板】杜教筛:求 $S_\varphi(n)$ 与 $S_\mu(n)$。要求 $O(n^{\frac 2 3})$。

  • $\varphi$:$\varphi * 1 = \text{Id}$
  • $\mu$:$\mu * 1 = \varepsilon$

直接杜教筛即可。

例 2:莫比乌斯反演 + 杜教筛

[Luogu P3768] 简单的数学题:求 $\sum\limits_{i=1}^n \sum\limits_{j=1}^n ij\gcd(i,j)$。模数为大质数。要求 $O(n^{\frac 2 3})$。

由莫反例 3 可得:

\[\begin{aligned} & \sum\limits_{i=1}^n \sum\limits_{j=1}^n ij\gcd(i,j) \\ =& \sum\limits_{T=1}^n \varphi(T)T^2 \times S_{\text{Id}}(\lfloor \dfrac n T \rfloor)^2 \end{aligned}\]

问题转化为求出 $\varphi \cdot \text{Id}_2$ 的基本和组。

《注意到》有 $(\varphi \cdot \text{Id}_2) * \text{Id}_2 = \text{Id}_3$。

杜教筛即可。

杜教筛嵌套

  • 常数次杜教筛嵌套,复杂度保持 $O(n^{\frac 2 3})$。
    • 假设你用 $d * \mu = 1$ 来计算 $d$ 的前缀和。
    • 首先用 $O(n^{\frac 2 3})$ 算出 $\mu$ 的基本和组。
    • 然后用 $O(n^{\frac 2 3})$ 算出 $d$ 的基本和组。
    • 总复杂度还是 $O(n^{\frac 2 3})$。

例 3:贝尔级数:系统地为积性函数构造杜教筛

[SP20173] DIVCNT2 - Counting Divisors (square):求 $\sum\limits_{i=1}^n d(i^2)$。要求 $O(n^{\frac 2 3})$。

定义一个积性函数 $f$ 的贝尔级数为一个形式幂级数:

\[f_p(x) = \sum\limits_{i=0}^\infty f(p_i) x_i\]

对于两个积性函数 $f,g$,$f*g$ 的贝尔级数等于 $f$ 与 $g$ 的贝尔级数相乘。

常见数论函数的贝尔级数:

  • $\varepsilon$:$1$
  • $\text{Id}_k$:$\dfrac 1 {1 - p^k x}$
    • $1$:$\dfrac 1 {1 - x}$
  • $\mu$:$1-x$
  • $(\mu \cdot \mu)$:$1+x$
  • $\sigma_k$:$\dfrac 1 {(1-x)(1 - p^k x)}$
    • $d$:$\dfrac 1 {(1-x)^2}$
  • $\varphi$:$\dfrac {1-x} {1-px}$

本题的函数($d \circ \text{Id}_2$)显然是积性函数,考虑其贝尔级数:

\[f_p(x) = \dfrac {1+x} {(1-x)^2}\]

不难发现:$f = (\mu \cdot \mu) * d$。

Trick:$(\mu \cdot \mu)$ 的前缀和能快速求。[Luogu P4318] 完全平方数

还有吗……?

OI 中会遇到的数论题目基本到此为止了。但是不排除一些毒瘤 [SDOI2018] 旧试题

再往后洲阁筛、Min_25 筛之类的东西我个人认为没有赛场上的实用价值。

就这样罢。