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\):
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 反演
Mobius 函数 \(\mu\)
逆元?两数相乘为 \(1\) 是乘法逆元,类似地,两函数相卷得到幺元 \(\epsilon\),则两函数互为卷积逆元。Mobius 函数实际上就是一个构造出的 \(I\) 的逆元,记作 \(\mu\)。
\(\mu\) 是一个积性函数,定义式为:
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\) 函数是为了满足下式:
\]
即:
\]
证明:\(n=1\) 时显然成立,仅需证明 \(n>1\) 时左式恒为 \(0\)。设 \(n=\prod p_i^{\alpha_i}\),显然仅需考虑左式中 \(d=\prod p_i\) 时的和。不妨设 \(n\) 含有素因子的集合为 \(P\),则左式有:
\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\) 的逆元”而不考虑其内部表达式,故多数情况不需要如此考虑其展开后的运算。
Mobius 反演
充分认识 \(\mu\) 之后,反演公式其实非常浅显。对于两个数论函数 \(f,g\),满足:
\]
证明:左式左右同时卷 \(\mu\) 即证 \(\Rightarrow\);右式左右同时卷 \(I\) 即证 \(\Leftarrow\)。
还有两种和式形式:
\]
\]
\((1)\) 即为卷积形式,已证,下证 \((2)\)。
证明,仅证 \(\Rightarrow\),倒推结论:
\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\)。
\sigma_0(n)&=\sum_{d|n}1\\
&=\sum_{d|n}I(d)I(\frac{n}d)\\
&=I^2(n)
\end{aligned}
\]
结论:
\]
欧拉函数 \(\varphi\)
定义式:\(\varphi(n)=\sum_{i=1}^n[i\perp n]\)。
\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 反演,下文亦如此。结论:
\]
反演魔法
例一
类似题目 Link.
给定 \(n,m,k\),求
\]
传说中的七倍经验题。直接来叭:
\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,一定要用熟。
例二
给定 \(T\) 组 \(n,m\),对于每组,求
\]
\(T\le10^4\),\(n,m\le10^7\)。
式子很简单,主要运用换元法
\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)\) 解决。
例三
令 \(\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)\),推导:
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\),有定义
\]
则任意一对 \(x\perp y\),带入
\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}\)(标准分解形式),有
\]
证略。我们来处理筛法中的特殊情况,设 \(p=p_k\) 为 \(x\) 的最小素因子,则应有 \(p^2|x\)。观察:
\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\) 很显然可以在筛法中处理。此后,就能得到
\]
问题解决。值得再次强调的是,Euler 筛法中的合数一定被其最小素因子筛掉。
筛 \(\operatorname{id}^k\mu\)
即 洛谷 P4449 的阶段性问题。
做题的时候,经常遇见此类很多个基础的积性函数卷起来的函数,它们亦可被线性筛。
同样的姿势,设 \(p\) 为 \(x\) 的最小素因子,且有 \(p^2|x\),观察:
\operatorname{id}^k\mu(x)=\sum_{d|x}d^k\mu(\frac{x}d)
\]
分类讨论第二个和式中的 \(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(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\) 积性。
接下来,我们从积性的角度着手,思考素数幂 \(p^k\) 处的点值。边界有:
\]
对于其他 \(k>1\):
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\),那么:
\]
简洁地结束问题。
\(\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!
Note -「Mobius 反演」光速入门的更多相关文章
- Note -「单位根反演」学习笔记
\(\mathcal{Preface}\) 单位根反演,顾名思义就是用单位根变换一类式子的形式.有关单位根的基本概念可见我的这篇博客. \(\mathcal{Formula}\) 单位根反演的 ...
- Note -「动态 DP」学习笔记
目录 「CF 750E」New Year and Old Subsequence 「洛谷 P4719」「模板」"动态 DP" & 动态树分治 「洛谷 P6021」洪水 「S ...
- Note -「Lagrange 插值」学习笔记
目录 问题引入 思考 Lagrange 插值法 插值过程 代码实现 实际应用 「洛谷 P4781」「模板」拉格朗日插值 「洛谷 P4463」calc 题意简述 数据规模 Solution Step 1 ...
- 「专题总结」LCT入门
上次xuefeng说我的专题总结(初探插头dp)太不适合入门了,所以这次丢一些题解包以外的东西. 关键是我自己也不会...急需梳理一下思路... (让我口胡数据结构???顺便推广一下全世界最短的lct ...
- ☆ [POI2007] ZAP-Queries 「莫比乌斯反演」
题目类型:莫比乌斯反演 传送门:>Here< 题意:求有多少对正整数对\((a,b)\),满足\(0<a<A\),\(0<b<B\),\(gcd(a,b)=d\) ...
- 「BZOJ 3529」「SDOI 2014」数表「莫比乌斯反演」
题意 有一张 \(n\times m\) 的数表,其第\(i\)行第\(j\)列的数值为能同时整除\(i\)和\(j\)的所有自然数之和. \(T\)组数据,询问对于给定的 \(n,m,a\) , 计 ...
- 「BZOJ 3994」「SDOI 2015」约数个数和「莫比乌斯反演」
题意 设\(d(x)\)为\(x\)的约数个数,求\(\sum_{i=1}^{n}\sum_{j=1}^{m}d(ij)\). 题解 首先证个公式: \[d(ij) = \sum_{x|i}\sum_ ...
- 「CF235E」Number Challenge「莫比乌斯反演」
一个结论:(从二维扩展来的,三维也是对的,证明可以考虑质因数分解) \[ d(ijk)=\sum_{i'|i}\sum_{j'|j}\sum_{k'|k}[\gcd(i',j')=1][\gcd(i' ...
- Note -「Min_25 筛」“你就说这素因子你要不要吧?你要不要?”
赛上想写,Track Lost 了属于是. \(\mathscr{Intro}\) Min_25 筛是用于求积性函数前缀和,同时顺带求出一些"有意思"的信息的筛法. 一 ...
随机推荐
- 你不得不了解的Python3.x新特性
从 3.0 到 3.8,Python 3 已经更新了一波又一波,但似乎我们用起来和 2.7 没有太大区别?以前该怎么写 2.7 的代码现在就怎么写,只不过少数表达方式变了而已.在这篇文章中,作者介绍了 ...
- ADO.NET数据访问基础与综合应用2020年10月31日20:17:09学习笔记
四.创建数据表 1.数据表的名称. 2.表中的字段名.数据类型.是否可以为空.字段的约束.必备的字段(通常会有一个ID,表示实体的唯一性:可以直接手写,也可以使用种子标识自动生成,给定起始值,给定增长 ...
- Python函数与lambda 表达式(匿名函数)
Python函数 一.函数的作用 函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码段 函数能提高应用的模块性和代码的重复利用率 python 内置函数:https://docs.pytho ...
- 【vps】如何在vps上安装mirai机器人?
[vps]如何在vps上安装mirai机器人? 前言 由于某位师傅在群里设置了一个bot,吸引了我,所以我之前找他问了点bot的相关知识,这几天正好服务器搬迁,所以就在新服务器上再装一遍bot 1.安 ...
- 【C++】字符串处理
字符串处理 标签:c++ 目录 字符串处理 一.输入 1. scanf()函数 2. gets()函数 3. getchar()函数 二.输出 1. printf()函数 2. puts()函数: 3 ...
- 【刷题-PAT】A1126 Eulerian Path (25 分)
1126 Eulerian Path (25 分) In graph theory, an Eulerian path is a path in a graph which visits every ...
- Cesium中级教程7 - Geometry and Appearances 几何图形和外观
Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ 本教程将向您介绍提供使用Primitive API的几何图形和外 ...
- JavaCV的摄像头实战之二:本地窗口预览
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- ant -design vue a-tree 树形控件
话不多说,先上代码. <a-tree v-if="this.treeData && this.treeData.length > 0" ref=&quo ...
- rsync.sh
#!/bin/bash file1=`du -sm /var/www/vhosts/|awk '{print $1}'` ps=`ps -C rsync --no-header|wc -l` if [ ...