Note -「Mobius 反演」光速入门
UPD:修改了 Euler 筛法代码框架。
若无特别说明,\(x,y\) 等形式变量均 \(\in\mathbb N_+\);\(p\) 为素数。
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)\) 积性,后文详解。
Dirichlet 卷积
卷积是什么呢?对于任意三个函数 \(f,g,h\),若有:
则 \(h\) 是 \(f\) 和 \(g\) 的 \(\oplus\) 卷积。例如 \(\oplus\) 为加号,则 \(h\) 是 \(f\) 和 \(g\) 的普通卷积;若 \(\oplus\) 为异或,则 \(h\) 是 \(f\) 和 \(g\) 的异或卷积。
而当 \(\oplus\) 为乘号,\(f,g,h\) 为数论函数,有
此时 \(h\) 即为 \(f\) 和 \(g\) Dirichlet 卷积的结果。记为
当然,另一种表达方式为
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\):
Dirichlet 卷积中的特殊函数
Dirichlet 卷积既然已是一种函数间的运算,我们就有必要研究一些特殊的“运算值”。例如零元,幺元等。一些常用的函数如下:
- \(I(n)=1\),常数函数;
- \(\epsilon(n)=[n=1]\),单位函数,Dirichlet 卷积的(左、右)幺元;
- \(\operatorname{id}(n)=n\),恒等函数。
这三者看似无用,但它们之间的运算可以表达出常见的数论函数:
-
\(\varphi(n)\),欧拉函数;
-
\(\sigma_0(n)\),约数个数函数;
-
……
突然,Mobius 就提出一个问题:\(I\) 在 Dirichlet 卷积下的逆元是什么?
Mobius 函数 & Mobius 反演
Mobius 函数 \(\mu\)
逆元?两数相乘为 \(1\) 是乘法逆元,类似地,两函数相卷得到幺元 \(\epsilon\),则两函数互为卷积逆元。Mobius 函数实际上就是一个构造出的 \(I\) 的逆元,记作 \(\mu\)。
\(\mu\) 是一个积性函数,定义式为:
这样看着很臃肿。注意 \(\mu\) 是一个积性函数,我们只需要描述起在 \(p^c~(c\in\mathbb N_+)\) 处的点值。可以看出:
\(\mu\) 函数是为了满足下式:
即:
证明:\(n=1\) 时显然成立,仅需证明 \(n>1\) 时左式恒为 \(0\)。设 \(n=\prod p_i^{\alpha_i}\),显然仅需考虑左式中 \(d=\prod p_i\) 时的和。不妨设 \(n\) 含有素因子的集合为 \(P\),则左式有:
在此后的推导中,我们通常仅把 \(\mu\) 看做“\(I\) 的逆元”而不考虑其内部表达式,故多数情况不需要如此考虑其展开后的运算。
Mobius 反演
充分认识 \(\mu\) 之后,反演公式其实非常浅显。对于两个数论函数 \(f,g\),满足:
证明:左式左右同时卷 \(\mu\) 即证 \(\Rightarrow\);右式左右同时卷 \(I\) 即证 \(\Leftarrow\)。
还有两种和式形式:
\((1)\) 即为卷积形式,已证,下证 \((2)\)。
证明,仅证 \(\Rightarrow\),倒推结论:
基础应用
我们来推导几个常见的函数或式子。
约数个数 \(\sigma_0\)
定义式:\(\sigma_0(n)=\sum_{d|n}1\)。
结论:
欧拉函数 \(\varphi\)
定义式:\(\varphi(n)=\sum_{i=1}^n[i\perp n]\)。
标注 \(*\) 的步骤运用了 Mobius 反演,下文亦如此。结论:
反演魔法
例一
类似题目 Link.
给定 \(n,m,k\),求
传说中的七倍经验题。直接来叭:
\(\mathcal O(n)\) 预处理后整除分块即可 \(\mathcal O(\sqrt n)\) 求解。整除分块是莫反题中高频出现的 trick,一定要用熟。
例二
给定 \(T\) 组 \(n,m\),对于每组,求
\(T\le10^4\),\(n,m\le10^7\)。
式子很简单,主要运用换元法
再令 \(f(n)=n\sum_{d|n}d\mu(d)\),由于化简不来,我们转而证明它积性可直接筛,具体可见下文「线性筛 trick」。
最终 \(\mathcal O(n)-\mathcal O(\sqrt n)\) 解决。
例三
令 \(\sigma(n)\) 为 \(n\) 的约数之和。给出 \(T\) 个 \(n\),对于每个 \(n\),求
\(T\le5\times10^4\),\(n\le10^6\)。
只要睡醒了应该是有把 \(\max\) 拆开的意识的。原式化为
\(\sigma(i^2)\) 可证积性,直接筛出后一项。对于前一项,我们先来研究 \(\sigma(ij)\) 的性质:
引理:
证明:对于每个 \(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)\),推导:
筛出 \(\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\),有定义
则任意一对 \(x\perp y\),带入
第三步用了 \(x\perp y\) 的条件。可见 \(\sigma\) 积性,考虑如何筛。
小奥教会我们,对于 \(n=\prod p_i^{\alpha_i}\)(标准分解形式),有
证略。我们来处理筛法中的特殊情况,设 \(p=p_k\) 为 \(x\) 的最小素因子,则应有 \(p^2|x\)。观察:
乘积式很难直接修改某一项的值,所以我们需要对于每个 \(x\),记录其最小素因子的贡献,记作 \(\sigma_p(x)\),有
\(\sigma_p\) 很显然可以在筛法中处理。此后,就能得到
问题解决。值得再次强调的是,Euler 筛法中的合数一定被其最小素因子筛掉。
筛 \(\operatorname{id}^k\mu\)
即 洛谷 P4449 的阶段性问题。
做题的时候,经常遇见此类很多个基础的积性函数卷起来的函数,它们亦可被线性筛。
同样的姿势,设 \(p\) 为 \(x\) 的最小素因子,且有 \(p^2|x\),观察:
分类讨论第二个和式中的 \(d\):
- 不含新加入的素因子 \(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\),无贡献;
- 含有新加入的素因子 \(p\),亦对应第一个和式中的每个 \(d^k\mu(\frac{x}{dp})\),只不过 \(d\) 多了一个 \(p\),所以应为 \(d^kp^k\mu(\frac{x}{dp})\)。
综上:
筛 \(f(n)=n\sum_{d|n}d\mu(d)\)
这是上文的问题,我们得证明它能筛(积性),在得出它如何筛。
还是惯用手法,带入任意 \(x\perp y\):
果然积性。
当然,也可以用积性的延续性质。发现
亦能说明 \(f\) 积性。
接下来,我们从积性的角度着手,思考素数幂 \(p^k\) 处的点值。边界有:
对于其他 \(k>1\):
所以在筛法中,有 \(p^2|x\),那么:
简洁地结束问题。
\(\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 贡献 */
}
}
以前文求
为例,步骤如下:
-
常系数剔除:\(n\) 显然最后再乘上去。
-
形式变化:类似变化乘法卷积的操作,把式子变化成形如 \(\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) \] -
预处理上述 \(A(n)\),\(B(n)\) 的值。此处即筛出 \(\mu\) 和 \(\sigma\),预处理 \(\sigma\) 前缀和。
-
套用框架计算。
莫得什么难点。(
Conclusion
莫反题的难点一般不是莫反。(
Practice makes perfect. 式子多推一下自然能找到感觉。建议尝试自己推导文中的式子,再对照文中的推导看看是否可以优化。(当然我可能推得很细,也可能兔子就是要蠢一点 qwq。
终于写完了 qwq!