莫比乌斯反演
(PS:在评论区中众多dalao的催促下,我认真的写了三天三夜写完了这篇杜教筛,保证是精品!)
前言
(这大概是我第一次写学习笔记吧OvO)
可能每一个刚开始接触莫比乌斯反演的OIer,起初都会厌恶这个神奇的东西。(我也一样233)每一个人厌恶的原因有许多,可能是这个烦人的式子,也可能仅仅只是因为不理解\\(\\mu\\)函数而感到不爽。当然,莫比乌斯反演有一个小小的预备知识:整除分块
那么我们先从莫比乌斯反演中最基础的莫比乌斯函数\\(\\mu\\)开始说起:
莫比乌斯函数
- 首先,我们可以先明确一点,莫比乌斯函数并不是什么很高大上的东西,它其实只是一个由容斥系数所构成的函数。\\(\\mu(d)\\)的定义是:
- 当\\(d=1\\)时,\\(\\mu(d)=1\\);
- 当\\(d=\\Pi_{i=1}^{k}p_i\\)且\\(p_i\\)为互异素数时,\\(\\mu(d)=(-1)^k\\)。(说直白点,就是\\(d\\)分解质因数后,没有幂次大于平方的质因子,此时函数值根据分解的个数决定);
- 只要当\\(d\\)含有任何质因子的幂次大于等于2,则函数值为0.
- 当然,莫比乌斯函数也有很多有趣的性质:
- 对于任意正整数\\(n\\),\\(\\sum_{d|n}\\mu(d)=[n=1]\\)。(\\([n=1]\\)表示只有当\\(n=1\\)成立时,返回值为\\(1\\);否则,值为\\(0\\);(这个就是用\\(\\mu\\)是容斥系数的性质可以证明)(PS:这一条性质是莫比乌斯反演中最常用的)
- 对于任意正整数\\(n\\),\\(\\sum_{d|n}\\frac{\\mu(d)}{d}=\\frac{\\phi(n)}{n}\\)。(这个性质很奇妙,它把欧拉函数和莫比乌斯函数结合起来,或许我之后写杜教筛的学习笔记时会去证明吧)
- 程序实现并不难,我们可以在线性筛素数的程序上略作修改,便可以筛出\\(\\mu\\)函数。
- 那我还是给一段线筛的代码吧
void get_mu(int n)
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i]){prim[++cnt]=i;mu[i]=-1;}
for(int j=1;j<=cnt&&prim[j]*i<=n;j++)
{
vis[prim[j]*i]=1;
if(i%prim[j]==0)break;
else mu[i*prim[j]]=-mu[i];
}
}
}
- 那么,莫比乌斯函数就这么告一段落了。
莫比乌斯反演
- 解决完莫比乌斯函数的问题后,我们便迎来了重头戏莫比乌斯反演
- 定理:F(n)和f(n)是定义在非负整数集合上的两个函数,并且满足条件:
\\[F(n)=\\sum_{d|n}f(d)
\\]
那么存在一个结论:
\\[f(n)=\\sum_{d|n}\\mu(d)F(\\lfloor\\frac{n}{d}\\rfloor)
\\]
这个定理就称作莫比乌斯反演定理。
- 莫比乌斯反演的证明主要有两种方式,其中一种就是通过定义来证明;另外一种,我则是会在杜教筛中提到(利用狄利克雷卷积)。那么我先来说一说第一种证明方法:
\\[\\sum_{d|n}\\mu(d)F(\\lfloor\\frac{n}{d}\\rfloor)=\\sum_{d|n}\\mu(d)\\sum_{i|\\lfloor\\frac{n}{d}\\rfloor}f(i)
\\]
\\[=\\sum_{i|n}f(i)\\sum_{d|\\lfloor\\frac{n}{i}\\rfloor}\\mu(d)=f(n)
\\]
(PS:如果不知道最后一步怎么来的,可以再去看性质一,至于和式的变换,就自己脑补一下吧)
- 当然,莫比乌斯反演有另外的一种形式,当\\(F(n)\\)和\\(f(n)\\)满足:
\\[F(n)=\\sum_{n|d}f(d)
\\]
可以推出:
\\[f(n)=\\sum_{n|d}\\mu(\\frac{d}{n})F(d)
\\]
- 感觉这个式子,可能在莫比乌斯反演中更加好用。
那么,莫比乌斯反演的基本内容就说完了。知道了这些内容,就已经可以解决一些有关的问题了。我做了一些关于莫比乌斯反演的题,具体题解可以看看我博客中的内容。
题目
YY的gcd
[POI2007]ZAP-Queries
[SDOI2015]约数个数和
[HAOI2011]Problem b
洛谷P1829 [国家集训队]Crash的数字表格
(未完,待更新)