Note -「Mobius 反演」光速入门
阅读原文时间:2023年07月08日阅读:2

目录

Preface

  我们称任意 \(f:\mathbb N_+\rightarrow\mathbb C\) 为一个数论函数。

积性函数

  对于两个数论函数 \(f\),若对于任意 \(x\perp y\)(即 \(x,y\) 互素,或说 \(\gcd(x,y)=1\)),都有 \(f(x)\cdot f(y)=f(xy)\),那么称此数论函数是积性函数,且显然有 \(f(1)=1\)。

  可以发现,在此定义下,我们只需要知道该函数在素数幂(\(p^c~(c\in\mathbb N_+)\))处的点值,就能还原整个函数。

  特别地,若任意 \(x,y\) 都有 \(f(x)\cdot f(y)=f(xy)\),那么称此数论函数是完全积性函数。例如,\(I(n)=1\) 是一个常函数,自然可以得到它是一个完全积性函数。

  重要的一点是,绝大部分积性函数可以在 Euler 筛法的框架下快速求出所有点值。

  积性在一些函数运算中得以延续。设 \(f,g\) 为积性函数,\(k\in\mathbb N_+\),则:

  • \(h(n)=(f(n))^k\) 积性(不写作 \(f^k(n)\) 是为区别 Dirichlet 卷积);

  • \(h(n)=f(n^k)\) 积性;

  • \(h(n)=f(n)\cdot g(n)\) 积性;

  • \(h(n)=(f\star g)(n)\) 积性,后文详解。

      卷积是什么呢?对于任意三个函数 \(f,g,h\),若有:

\[h(k)=\sum_{i\oplus j=k}f(i)\cdot g(j)
\]

  则 \(h\) 是 \(f\) 和 \(g\) 的 \(\oplus\) 卷积。例如 \(\oplus\) 为加号,则 \(h\) 是 \(f\) 和 \(g\) 的普通卷积;若 \(\oplus\) 为异或,则 \(h\) 是 \(f\) 和 \(g\) 的异或卷积。

  而当 \(\oplus\) 为乘号,\(f,g,h\) 为数论函数,有

\[h(k)=\sum_{ij=k}f(i)\cdot g(j)
\]

  此时 \(h\) 即为 \(f\) 和 \(g\) Dirichlet 卷积的结果。记为

\[h=f\star g
\]

  当然,另一种表达方式为

\[h(k)=\sum_{i|n}f(i)\cdot g(\frac{k}i)
\]

  Dirichlet 卷积有以下性质:

  • 交换律:\(f\star g=g\star f\);

  • 结合律:\((f\star g)\star h=f\star(g\star h)\);

  • 分配律:\(f\star(g+h)=f\star g+f\star h\)。

      带入可证,此处略过。

      Dirichlet 卷积还有一个重要性质:若 \(f,g\) 积性,则 \(h=f\star g\) 积性

      证明:对于任意 \(x\perp y\):

\[\begin{aligned}
h(x)h(y)&=\left(\sum_{d_x|x}f(d_x)g(\frac{x}{d_x})\right)\left(\sum_{d_y|y}f(d_y)g(\frac{y}{d_y}) \right)\\
&=\sum_{d_x|x}\sum_{d_y|y}f(d_x)f(d_y)g(\frac{x}{d_x})g(\frac{y}{d_y})\\
&=\sum_{d_x|x}\sum_{d_y|y}f(d_xd_y)g(\frac{xy}{d_xd_y})\\
&=\sum_{d|xy}f(d)g(\frac{xy}d)\\
&=h(xy)
\end{aligned}
\]

Dirichlet 卷积中的特殊函数

  Dirichlet 卷积既然已是一种函数间的运算,我们就有必要研究一些特殊的“运算值”。例如零元,幺元等。一些常用的函数如下:

  • \(I(n)=1\),常数函数;

  • \(\epsilon(n)=[n=1]\),单位函数,Dirichlet 卷积的(左、右)幺元;

  • \(\operatorname{id}(n)=n\),恒等函数。

      这三者看似无用,但它们之间的运算可以表达出常见的数论函数:

  • \(\varphi(n)\),欧拉函数;

  • \(\sigma_0(n)\),约数个数函数;

  • ……

      突然,Mobius 就提出一个问题:\(I\) 在 Dirichlet 卷积下的逆元是什么?

Mobius 函数 & Mobius 反演

  逆元?两数相乘为 \(1\) 是乘法逆元,类似地,两函数相卷得到幺元 \(\epsilon\),则两函数互为卷积逆元。Mobius 函数实际上就是一个构造出的 \(I\) 的逆元,记作 \(\mu\)。

  \(\mu\) 是一个积性函数,定义式为:

\[\mu(n)=\begin{cases}
1&n=1\\
(-1)^k&n=p_1p_2\cdots p_k,~~~~p\text{ 为两两不同的素数}\\
0&\text{otherwise}
\end{cases}
\]

  这样看着很臃肿。注意 \(\mu\) 是一个积性函数,我们只需要描述起在 \(p^c~(c\in\mathbb N_+)\) 处的点值。可以看出:

\[\mu(p^c)=[c=1](-1)
\]

  \(\mu\) 函数是为了满足下式:

\[I\star\mu=\epsilon
\]

  即:

\[\sum_{d|n}\mu(d)=[n=1]
\]

  证明:\(n=1\) 时显然成立,仅需证明 \(n>1\) 时左式恒为 \(0\)。设 \(n=\prod p_i^{\alpha_i}\),显然仅需考虑左式中 \(d=\prod p_i\) 时的和。不妨设 \(n\) 含有素因子的集合为 \(P\),则左式有:

\[\begin{aligned}
\sum_{d|n}\mu(d)&=\sum_{S\subseteq P}\mu(\prod_{p\in S}p)\\
&=\sum_{S\subseteq P}(-1)^{|S|}\\
&=\sum_{|S|\in[0,|P|]}\binom{|P|}{|S|}(-1)^{|S|}\\
&=(1-1)^{|P|}\\
&=0^{|P|}~~~~(|P|>0)\\
&=0
\end{aligned}
\]

  在此后的推导中,我们通常仅把 \(\mu\) 看做“\(I\) 的逆元”而不考虑其内部表达式,故多数情况不需要如此考虑其展开后的运算。

  充分认识 \(\mu\) 之后,反演公式其实非常浅显。对于两个数论函数 \(f,g\),满足:

\[f=g\star I\Longleftrightarrow g=f\star\mu
\]

  证明:左式左右同时卷 \(\mu\) 即证 \(\Rightarrow\);右式左右同时卷 \(I\) 即证 \(\Leftarrow\)。

  还有两种和式形式:

\[f(n)=\sum_{d|n}g(d)\Longleftrightarrow g(n)=\sum_{d|n}f(d)\mu(\frac{n}d)\tag1
\]

\[f(n)=\sum_{n|d}g(d)\Longleftrightarrow g(n)=\sum_{n|d}f(d)\mu(\frac{d}n)\tag2
\]

  \((1)\) 即为卷积形式,已证,下证 \((2)\)。

  证明,仅证 \(\Rightarrow\),倒推结论:

\[\begin{aligned}
\sum_{n|d}f(d)\mu(\frac{d}n)&=\sum_{k=1}^{+\infty}f(kn)\mu(k)\\
&=\sum_{k=1}^{+\infty}\mu(k)\sum_{kn|d}f(d)\\
&=\sum_{n|d}g(d)\sum_{k|\frac{n}d}\mu(k)\\
&=\sum_{n|d}g(d)\epsilon(\frac{n}d)\\
&=g(n)
\end{aligned}
\]

基础应用

  我们来推导几个常见的函数或式子。

约数个数 \(\sigma_0\)

  定义式:\(\sigma_0(n)=\sum_{d|n}1\)。

\[\begin{aligned}
\sigma_0(n)&=\sum_{d|n}1\\
&=\sum_{d|n}I(d)I(\frac{n}d)\\
&=I^2(n)
\end{aligned}
\]

  结论:

\[\sigma_0=I^2
\]

欧拉函数 \(\varphi\)

  定义式:\(\varphi(n)=\sum_{i=1}^n[i\perp n]\)。

\[\begin{aligned}
\varphi(n)&=\sum_{i=1}^n[i\perp n]\\
&=\sum_{i=1}^n\sum_{d|i\land d|n}\mu(d)~~~~*\\
&=\sum_{d|n}\mu(d)\frac{n}d\\
&=\sum_{d|n}\mu(d)\operatorname{id}(\frac{n}d)\\
&=(\mu\star\operatorname{id})(n)
\end{aligned}
\]

  标注 \(*\) 的步骤运用了 Mobius 反演,下文亦如此。结论:

\[\varphi=\mu\star\operatorname{id}
\]

反演魔法

例一

  类似题目 Link.

  给定 \(n,m,k\),求

\[\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=k]
\]

  传说中的七倍经验题。直接来叭:

\[\begin{aligned}
\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=k]&=\sum_{i=1}^{\lfloor\frac{n}k\rfloor}\sum_{j=1}^{\lfloor\frac{m}k\rfloor}[i\perp j]\\
&=\sum_{i=1}^{\lfloor\frac{n}k\rfloor}\sum_{j=1}^{\lfloor\frac{m}k\rfloor}\sum_{d|i\land d|j}\mu(d)~~~~*\\
&=\sum_{d=1}^{\min\{\lfloor\frac{n}k\rfloor,\lfloor\frac{m}k\rfloor\}}\mu(d)\lfloor\frac{n}{kd}\rfloor\lfloor\frac{m}{kd}\rfloor
\end{aligned}
\]

  \(\mathcal O(n)\) 预处理后整除分块即可 \(\mathcal O(\sqrt n)\) 求解。整除分块是莫反题中高频出现的 trick,一定要用熟。

例二

  BZOJ 2693.

  给定 \(T\) 组 \(n,m\),对于每组,求

\[\sum_{i=1}^n\sum_{j=1}^m\operatorname{lcm}(i,j)\bmod(10^8+9)
\]

  \(T\le10^4\),\(n,m\le10^7\)。

  式子很简单,主要运用换元法

\[\begin{aligned}
\sum_{i=1}^n\sum_{j=1}^m\operatorname{lcm}(i,j)&=\sum_{d=1}^nd\sum_{i=1}^{\lfloor\frac{n}d\rfloor}\sum_{i=1}^{\lfloor\frac{m}d\rfloor}ij[i\perp j]\\
&=\sum_{d=1}^nd\sum_{d'=1}^{\lfloor\frac{n}{d}\rfloor}S(\lfloor\frac{n}{dd'}\rfloor)S(\lfloor\frac{m}{dd'}\rfloor)d'^2~~\text{let }S(n)=\frac{n(n+1)}2\\ &=\sum_{T=1}^nS(\lfloor\frac{n}T\rfloor)S(\lfloor\frac{m}T\rfloor)T\sum_{d|T}d\mu(d)\text{let } T=dd'~~*
\end{aligned}
\]

  再令 \(f(n)=n\sum_{d|n}d\mu(d)\),由于化简不来,我们转而证明它积性可直接筛,具体可见下文「线性筛 trick」。

  最终 \(\mathcal O(n)-\mathcal O(\sqrt n)\) 解决。

例三

  51nod 1584.

  令 \(\sigma(n)\) 为 \(n\) 的约数之和。给出 \(T\) 个 \(n\),对于每个 \(n\),求

\[\sum_{i=1}^n\sum_{j=1}^n\max\{i,j\}\sigma(ij)\bmod(10^9+7)
\]

  \(T\le5\times10^4\),\(n\le10^6\)。

  只要睡醒了应该是有把 \(\max\) 拆开的意识的。原式化为

\[2\sum_{i=1}^ni\sum_{j=1}^i\sigma(ij)-\sum_{i=1}^ni\sigma(i^2)
\]

  \(\sigma(i^2)\) 可证积性,直接筛出后一项。对于前一项,我们先来研究 \(\sigma(ij)\) 的性质:

  引理

\[\sigma(ij)=\sum_{x|i}\sum_{y|j}xy[x\perp \frac{j}y]
\]

  证明:对于每个 \(d|ij\),当且仅当 \(y=\gcd(d,j),~x=\frac{d}y\) 时被统计一次。考虑一个 \(a|d\land a|i\land a|j\),一定有 \(a\not|x\),不然就不可能有 \(x\perp \frac{j}y\),所以以上表述成立。

  利用引理,记 \(f(n)=n\sum_{i=1}^n\sigma(ni)\),推导:

\[\begin{aligned}
f(n)&=n\sum_{i=1}^n\sum_{x|n}\sum_{y|i}xy[x\perp\frac{i}y]\\
&=n\sum_{i=1}^n\sum_{x|n}\sum_{y|i}xy\sum_{d|x\land d|\frac{i}y}\mu(d)~~*\\ &=n\sum_{i=1}^n\sum_{d|n\land d|i}\mu(d)\sum_{x|n\land d|x}\sum_{y|i\land d|y}\frac{ix}y\\ &=n\sum_{i=1}^n\sum_{d|n\land d|i}\mu(d)\sum_{x|\frac{n}d}\sum_{y|\frac{i}d}\frac{ix}y,~~x,y\mbox{ 同时约掉 } d\\
&=n\sum_{i=1}^n\sum_{d|n\land d|i}\mu(d)\sigma(\frac{n}d)\sum_{y|\frac{i}d}\frac{i}y\\
&=n\sum_{i=1}^n\sum_{d|n\land d|i}\mu(d)\sigma(\frac{n}d)d\sum_{y|\frac{i}d}\frac{\frac{i}y}d\\
&=n\sum_{i=1}^n\sum_{d|n\land d|i}d\mu(d)\sigma(\frac{n}d)\sigma(\frac{i}d)\\
&=n\sum_{d|n}d\mu(d)\sigma(\frac{n}d)\sum_{i=1}^\frac{n}{d}\sigma(i)
\end{aligned}
\]

  筛出 \(\mu,\sigma\),枚举 \(d\) 和 \(\frac{n}d\),可以 \(\mathcal O(n\ln n)\) 算出所有 \(f\),具体可见下文「\(\mathcal O(n\ln n)\) 刷表 trick」以及我的题解

  最终,\(\mathcal O(n\ln n)-\mathcal O(1)\) 解决问题。

魔法中的 tricks

  毕竟 Mobius 反演不能把所有式子化成一眼能求。当我们在推导过程中卡住的时候,可以尝试用一些 trick “暴力”计算得到的式子,说不定就是正解呢!

线性筛 trick

  记住一句话:积性函数都能筛

  Euler 筛法的框架如下:

inline void sieve ( const int n ) {
      /* 初始化函数在 1 处的点值(=1) */
      for ( int i = 2; i <= n; ++i ) {
            if ( !vis[i] ) {
                  pr[++pn] = i];
                  /* 计算函数在素数处的点值 */
            }
            for ( int j = 1, t; ( t = i * pr[j] ) <= n; ++j ) {
                  vis[t] = true;
                  /* 注意:pr[j] 一定是 t 的最小素因子 */
                  if ( i % pr[j] ) {
                        /* pr[j] \not| i,利用积性处理 t 处点值 */
                  } else {
                        /* pr[j] | i,特殊处理 t 处点值 */
                        break;
                  }
            }
      }
}

  难点只有两个:

  • 如何判断某个函数是积性函数?

  • 如何处理计算的 \(t\) 处点值?

      对于前者,打表(迫真)和带入计算都是不错的选择。后者则需要根据函数表达式灵活处理,一般来说都是加减乘除能够解决的,某些情况(例如筛 \(\sigma_1\))需要额外记录信息。

筛 \(\sigma_1\)

  \(\sigma_1\) 也简记作 \(\sigma\),有定义

\[\sigma(n)=\sum_{d|n}d
\]

  则任意一对 \(x\perp y\),带入

\[\begin{aligned}
\sigma(x)\sigma(y)&=\sum_{d_x|x}d_x\sum_{d_y|y}d_y\\
&=\sum_{d_x|x,d_y|y}d_xd_y\\
&=\sum_{d|xy}d\\
&=\sigma(xy)
\end{aligned}
\]

  第三步用了 \(x\perp y\) 的条件。可见 \(\sigma\) 积性,考虑如何筛。

  小奥教会我们,对于 \(n=\prod p_i^{\alpha_i}\)(标准分解形式),有

\[\sigma(n)=\prod \sum_{j=0}^{\alpha_i}p_i^j
\]

  证略。我们来处理筛法中的特殊情况,设 \(p=p_k\) 为 \(x\) 的最小素因子,则应有 \(p^2|x\)。观察:

\[\sigma(\frac{x}p)=\left(\prod_{p_i\not=p}\sum_{j=0}^{\alpha_i}p_i^j\right)\left(\sum_{j=0}^{\alpha_k}p^j\right)\\
\sigma(x)=\left(\prod_{p_i\not=p}\sum_{j=0}^{\alpha_i}p_i^j\right)\left(\sum_{j=0}^{\alpha_k+1}p^j\right)
\]

  乘积式很难直接修改某一项的值,所以我们需要对于每个 \(x\),记录其最小素因子的贡献,记作 \(\sigma_p(x)\),有

\[\sigma_p(x)=\sum_{j=0}^{\alpha_k}p^j
\]

  \(\sigma_p\) 很显然可以在筛法中处理。此后,就能得到

\[\sigma(x)=\frac{\sigma(\frac{x}p)}{\sigma_p(\frac{x}p)}\sigma_p(x)
\]

  问题解决。值得再次强调的是,Euler 筛法中的合数一定被其最小素因子筛掉

筛 \(\operatorname{id}^k\mu\)

  即 洛谷 P4449 的阶段性问题。

  做题的时候,经常遇见此类很多个基础的积性函数卷起来的函数,它们亦可被线性筛。

  同样的姿势,设 \(p\) 为 \(x\) 的最小素因子,且有 \(p^2|x\),观察:

\[\operatorname{id}^k\mu(\frac{x}p)=\sum_{d|\frac{x}p}d^k\mu(\frac{x}{dp})\\
\operatorname{id}^k\mu(x)=\sum_{d|x}d^k\mu(\frac{x}d)
\]

  分类讨论第二个和式中的 \(d\):

  1. 不含新加入的素因子 \(p\),对应了第一个和式中的每个 \(d^k\mu(\frac{x}{dp})\),只不过 \(x\) 多了一个 \(p\),所以应为 \(d^k\mu(\frac{x}d)\)。由于 \(p^2|x\),且 \(d|\frac{x}p\Rightarrow p|\frac{x}d\),故 \(\mu(x)=\mu(\frac{x}d)=0\),无贡献;

  2. 含有新加入的素因子 \(p\),亦对应第一个和式中的每个 \(d^k\mu(\frac{x}{dp})\),只不过 \(d\) 多了一个 \(p\),所以应为 \(d^kp^k\mu(\frac{x}{dp})\)。

      综上:

\[\operatorname{id}^k\mu(x)=p^k(\operatorname{id}^k\mu)(\frac{x}p)
\]

筛 \(f(n)=n\sum_{d|n}d\mu(d)\)

  这是上文的问题,我们得证明它能筛(积性),在得出它如何筛。

  还是惯用手法,带入任意 \(x\perp y\):

\[\begin{aligned}
f(x)f(y)&=\left( x\sum_{d_x|x}d_x\mu(d_x) \right)\left( y\sum_{d_y|y}d_y\mu(d_y) \right)\\
&=xy\sum_{d_x|x,d_y|y}d_xd_y\mu(d_x)\mu(d_y)\\
&=xy\sum_{d|xy}d\mu(d)\\
&=f(xy)
\end{aligned}
\]

  果然积性。

  当然,也可以用积性的延续性质。发现

\[f=((\mu\cdot\operatorname{id})\star I)\cdot\operatorname{id}
\]

  亦能说明 \(f\) 积性。

  接下来,我们从积性的角度着手,思考素数幂 \(p^k\) 处的点值。边界有:

\[f(p)=p(1-p)
\]

  对于其他 \(k>1\):

\[\begin{aligned}
f(p^k)&=p^k\sum_{i=0}^kp^i\mu(p^i)\\
&=p^k(1-p)\\
&=pf(p^{k-1})
\end{aligned}
\]

  所以在筛法中,有 \(p^2|x\),那么:

\[f(x)=pf(\frac{x}p)
\]

  简洁地结束问题。

\(\mathcal O(n\ln n)\) 刷表 trick

  基于 \(\sum_{i=1}^n\frac{n}i=\mathcal O(n\ln n)\),很多时候可以把 Dirichlet 卷积形式的函数暴力打表出来。框架如下:

for ( int i = 1; i <= MAXN; ++i ) {
    for ( int j = 1, t; ( t = i * j ) <= MAXN; ++j ) {
        /* 用 i 和 j 的信息对 t=i*j 贡献 */
    }
}

  以前文求

\[f(n)=n\sum_{d|n}d\mu(d)\sigma(\frac{n}d)\sum_{i=1}^\frac{n}{d}\sigma(i)
\]

  为例,步骤如下:

  1. 常系数剔除:\(n\) 显然最后再乘上去。

  2. 形式变化:类似变化乘法卷积的操作,把式子变化成形如 \(\sum_{d|n}A(d)B(\frac{n}d)\) 的形式。此处有

    \[\frac{f(n)}n=\sum_{d|n}\left(d\mu(d)\right)\left(\sigma(\frac{n}d)\sum_{i=1}^{\frac{n}d}\sigma(i)\right)
    \]

  3. 预处理上述 \(A(n)\),\(B(n)\) 的值。此处即筛出 \(\mu\) 和 \(\sigma\),预处理 \(\sigma\) 前缀和。

  4. 套用框架计算。

      莫得什么难点。(

Conclusion

  莫反题的难点一般不是莫反。(

  Practice makes perfect. 式子多推一下自然能找到感觉。建议尝试自己推导文中的式子,再对照文中的推导看看是否可以优化。(当然我可能推得很细,也可能兔子就是要蠢一点 qwq。

  更多莫反题可在 OI-Wiki 以及 我的博客 中挑选嗷~

  终于写完了 qwq!