【开坑】莫比乌斯反演快速入门指南
shadowice1984 · · 个人记录
可能大多数人和我一样第一眼接触莫比乌斯反演的时候自己是懵逼的
数学真珂啪还是学OI好了
等等为什么OI考试里面会有纯数学题?
提到莫比乌斯反演的话,就是这类题目标志性的长而复杂的和式运算,以及一个标志性的技法——交换求和号了,这也正是这类题目的难点
不过莫比乌斯反演的套路性还是相当强的,掌握了一般技巧之后做简单的反演题应该不成问题
那么,看完本篇博客,希望诸位可以掌握
关于
基本的和式运算技巧和交换求和号的知识
莫比乌斯容斥公式
如何列式子和推式子
本博客仅供介绍莫比乌斯反演入门,关于除数函数的反演不会介绍
Part 1 莫比乌斯容斥公式
事实上这个公式正是莫比乌斯反演的本体
不过,由于使用这个公式之后等待你的将会是一系列长到不行的求和号变换,所以仅仅记住这个公式是做不出题来的
很简单,就两句话,若数列
则
其中函数
上面的式子反过来依然成立,也就是是说如果g满足下面的式子可以推出上面的式子
(可以跳过的)证明
先来证明上面的式子可以推出下面的式子
因为我们已知了
所以说我们可以简单粗暴的把上面的式子代入进去
然后接下来我们发现
这两个限制条件等价于这组限制条件
也等价于这两组限制条件
当然也等价于这两组限制条件
所以我们就可以愉快的将
还记得上面关于
也就是
Quite Easily Done 证明完毕
然后将已知下面的式子推上面的式子的证明过程交(甩)给(锅)读者思考吧~
Part 2 \mu 和\phi 以及\epsilon
可能关于
但是莫比乌斯反演当中非常关键的函数还有另外两个
先来介绍一下函数
然后介绍另一个看起来没什么卵用的函数
最后是我们上一节已经提及的函数
尽管已经有了一个这样的定义(倒不如说我们就是为了这个性质才构造出了函数
不过如果我们要求莫比乌斯函数的值的话,更加好的方式是使用下面这个定义
1.如果n的约数中存在平方数,则
2.对于其他情况,如果n有奇数个互异的质因子,
当然你可能会有一个问题,为什么上面的两个定义是等价的?
下面是可以跳过的证明
先来看一下
我们发现事实上满足这个定义的无穷数列
所以我们现在只需要证明根据
首先我们将n质因数分解,假设n有p个不同的质因子
那么我们会发现你枚举约数的过程相当于选择一些质因子(可以重复选)把他们乘起来,就得到了一个n的约数
但是如果同一个质数被选了两次,得到的约数就有平方约数了,此时的
因此真正有符号的
而
种
我们已经发现莫比乌斯容斥公式在解决某些问题上可能有不错的效果,比如说一个原来根本没法求的函数我们套个公式容斥下就可以求出他来了
只是还是有个问题是我们怎么求莫比乌斯函数的值
总不能暴力质因数分解然后求吧(不过如果n很大质因数分解是最快的做法)
不过我们发现一个关于
那就是如果
如果一个函数有类似于
好了那么积性函数和线性筛有什么关系呢?
这里我们先粘一份线性筛的代码
/*1*/ int pri[N];int ct;bool book[N];
/*2*/ for(int i=2;i<=N;i++)
/*3*/ {
/*4*/ if(!book[i])pri[++ct]=i;
/*5*/ for(int j=1;j<=ct&&i*pri[j]<=N;j++)
/*6*/ {
/*7*/ book[i*pri[j]]=true;
/*8*/ if(i%pri[j]==0)break;
/*9*/ }
/*10*/ }
观察一下线性筛的第7行代码
除非我们执行了第8行代码结束了循环,否则
正确性显然,因为在第8行break掉时质数是i的最小质因子,所以之前的质数必然和i互质
那么假设说我们已知了
问题来了如果我们执行了第8行代码的话该如何计算
如果第8行代码被执行了,那么意味着
所以说
递推的边界条件是
同理我们发现
不巧的是我们的确可以像递推
有个好消息是如果我们执行了第8行代码的时候
这里给出上边的式子的一个小证明(不过不想看证明的直接记结论也没什么关系)
由于
由于也就是质因数分解
那么
然后让我们回过头来看当我们执行了线性筛代码中的第8行时的情况,现在我们已经知道
那么我们发现
又因为
那么剩下的事情就好说了,既然
然后给出线性筛筛
这个是筛
int pri[N+10];int book[N+10];int mu[N+10];int ct;
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!book[i])pri[++ct]=i,mu[i]=-1;
for(int j=1;j<=ct&&i*pri[j]<=n;j++)
{
book[i*pri[j]]=true;
if(i%pri[j]==0){mu[i*pri[j]]=0;break;}else mu[i*pri[j]]=-mu[i];
}
}
这个是筛
int pri[N+10];int book[N+10];int phi[N+10];int ct;
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!book[i])pri[++ct]=i,phi[i]=i-1;
for(int j=1;j<=ct&&i*pri[j]<=n;j++)
{
book[i*pri[j]]=true;
if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}
else phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
Part4 狄利克雷卷积和常用的反演结论
其实这里介绍狄利克雷卷积主要是方便接下来写式子的时候不会写的太长
还记得我们一开始讲的莫比乌斯容斥公式吗?
仔细看第二个式子