省选算法学习-数论-莫比乌斯反演+杜教筛
唔姆~于是今天来讲莫比乌斯反演~
莫比乌斯反演又称懵逼钨丝反演,是一种让人一看就一脸懵逼的算法
为了让大家不再懵逼,今天我来换一种讲法,一种不同于大部分参考书和博客的讲法,来介绍这个莫比乌斯反演
备注:如果你对狄利克雷卷积表示的方法并不熟悉,推荐你在纸上把卷积转化成sigma的形式来看,这样也可以增强你对狄利克雷卷积的理解
备注++:想真正学好这个算法,请认真在纸上把没有一遍看懂的地方推导一遍,确保每个式子都看明白了再继续
Part I 前置技能
积性函数
首先,我们定义整数集合上的数论函数:定义域和值域都在整数集合中的函数称为“数论函数”
(真正的数论函数定义有所不同,可以自行参考维基)
那么积性函数就是这样的一类数论函数:
若函数$f$是积性函数,那么对于任意$gcd\left(i,j\right)=1$,有$f\left(ij\right)=f\left(i\right)\ast f\left(j\right)$
如果函数$f$在$gcd\left(i,j\right)\neq1$时也满足后面的条件,称函数$f$为完全积性函数
常见的积性函数:
$\mu\left(i\right)$,莫比乌斯函数
$\varphi\left(i\right)$,欧拉函数
$d\left(i\right)$,约数个数函数
$\sigma\left(i\right)$,约数和函数
常见的完全积性函数(注意完全积性函数一定是积性函数)
$I\left(i\right)=1$,常函数
$\varepsilon\left(i\right)=\left[i=1\right]$,单位函数
$id\left(i\right)=i$,恒等函数
狄利克雷卷积
嗯……这个东西,是今天我要讲的大部分东西的基础
那么狄利克雷卷积就是两个数论函数,通过一定的方法相乘:
定义$\left(g\ast f\right)\left(i\right)=F$,我们称F函数是g和f函数关于i的狄利克雷卷积
F的计算方式如下:
$F\left(i\right)=\sum_{d|i}g\left(d\right)f\left(\frac id\right)$
还是比较好理解的吧?
狄利克雷卷积满足交换律、结合律,并且有一些经典的结论:
$\left(\mu\ast I\right)=\varepsilon$
$\left(\varphi\ast I\right)=id$
$\left(\mu\ast id\right)=\varphi$
$\left(I\ast I\right)=d$
$\left(I\ast id\right)=\sigma$
其中前面三个,在莫比乌斯反演以及杜教筛中的应用很广泛,后面两个在解决大部分积性函数题目时候也有很大的作用
Part II 莫比乌斯函数/莫比乌斯反演
莫比乌斯函数
前面已经提到过这个东西......名字听起来很高大上对不对~
实际上它的定义不是特别高大上
定义莫比乌斯函数$\mu$
当$i=1$时,$\mu\left(i\right)=1$
当$i=\prod_{i=1}^{n}p_i^1$,其中$p_i$是互不相同的质数时,$\mu\left(i\right)=\left(-1\right)^n$
其余时候$\mu\left(i\right)=0$
$\mu$函数的两个最重要的性质,在上文中都已经用狄利克雷卷积的形式写过了
莫比乌斯函数同时也是接下来的莫比乌斯反演的主角
莫比乌斯反演
莫比乌斯反演是一个数论反演。当初发明它的主要目的是为了简化计算(1718世纪的时候)
它的原理基于这条式子:
$\left(\mu\ast I\right)=\varepsilon$
我们来看一个莫比乌斯反演的实例:
设$f=\left(g\ast I\right)$
两边同时卷积一个$\mu$,变成
$f\ast\mu=g\ast I\ast\mu$
$f\ast\mu=g\ast\varepsilon=g$
莫比乌斯反演就完成了
如果写成sigma的形式就是这样的:
如果
$f\left(d\right)=\sum_{i|d}g\left(i\right)$
那么
$g\left(d\right)=\sum_{i|d}f\left(i\right)\mu\left(\frac di\right)$
这是一种形式
还有一种形式是这样的:
如果
$f\left(d\right)=\sum_{d|i}g\left(i\right)$
那么
$g\left(i\right)=\sum_{i|d}f\left(d\right)\mu\left(\frac di\right)$
好像在大部分莫比乌斯反演题目中后面再这一种形式更常见一些
可以把他们两个理解为“对一个东西的所有约数求和”以及“对一个东西的所有倍数求和”然后反演
详细的纯理论证明可以参考这里:https://oi-wiki.org/math/mobius/
为了加深理解,我们先来看一个例子:HDU1695
注意这里面就是把一个不太好求的东西求了一个和,然后变成了一个很好求的东西,再通过反演把它反向算出来
再来看下一个例子:求
$\sum_{i=1}^{n}\sum_{j=1}^{m}gcd\left(i,j\right)$
我们做一步变形,一步非常重要的变形:把$gcd\left(i,j\right)$的值提出来,变成:
$\sum_{d=1}^{n}d\sum_{i=1}^{n}\sum_{j=1}^{m}\left[gcd\left(i,j\right)=d\right]$
这一步非常重要,一定要好好理解再继续,因为它是一个超级常用的技巧
下一步,发现后面$gcd\left(i,j\right)=d$这里的$d$很烦呐,把它除上去:
$\sum_{d=1}^{n}d\sum_{i=1}^{\frac nd}\sum_{j=1}^{\frac md}\left[gcd\left(i,j\right)=1\right]$
看到了吗?这就完成了向HDU1695的转变,后面就反演一下,变成这个形式:
$\sum_{d=1}^{n}d\sum_{i=1}^{n}\mu\left(i\right)\frac n{id}\frac m{id}$
设$D=id$,我们先枚举D再枚举D的约数d,变成这个形式
$\sum_{D=1}^{N}\sum_{d|D}d\mu\left(\frac Dd\right)\frac n{id}\frac m{id}$
最后面两项提到前面去,变成
$\sum_{D=1}^{N}\frac n{D}\frac m{D}\sum_{d|D}d\mu\left(\frac Dd\right)$
发现后面的是一个卷积的形式,就是$\left(\mu\ast id\right)=\varphi$
所以得到最终结果:
$\sum_{D=1}^{N}\frac n{D}\frac m{D}\varphi\left(D\right)$
然后数论分块技巧,在$O\left(\sqrt n\right)$下解决
关于更多莫比乌斯反演的题目,可以看:
Part III 杜教筛
基本而言,杜教筛解决的是这样的一类问题:
对于一个积性函数$f$,求它的前缀和$\sum_{i=1}^{n}f\left(i\right)$
别急,我知道你会线性筛,所以n<=10^10
显然线性时间复杂度的算法就解决不了了
但是杜教非常厉害,他发明了一个利用卷积的方法,强行把求前缀和的算法优化到了$O\left(n^\frac{2}{3}\right)$
下面我们就来看看杜教是怎么实现这个过程的
我们设$S\left(n\right)=\sum_{i=1}^{n}f\left(i\right)$,其中$f$是一个积性函数
我们再设一个积性函数$g$,并让它和$f$卷积后求前缀和,就是:
$\sum_{i=1}^{n}\left(g\ast f\right)\left(i\right)=\sum_{i=1}^{n}\sum_{d|i}g\left(d\right)f\left(\frac id\right)$
把$g\left(d\right)$提出来,先枚举$d$再枚举$d$的倍数$i$,变成:
$\sum_{d=1}^{n}g\left(d\right)\sum_{d|i}f\left(\frac id\right)=\sum_{d=1}^{n}g\left(d\right)\sum_{i=1}^{\frac nd}f\left(i\right)=\sum_{d=1}^{n}g\left(d\right)S\left(\frac nd\right)$
上面这个东西就是积性函数$g$和$f$卷积后求出来的前缀和
恒等变形一下,我们有这个式子:
$g\left(1\right)S\left(n\right)=\sum_{i=1}^{n}g\left(i\right)S\left(\frac nd\right)-\sum_{i=2}^{n}g\left(i\right)S\left(\frac nd\right)$
等号右边的第一坨东西我们化成卷积的形式:
$g\left(1\right)S\left(n\right)=\sum_{i=1}^{n}\left(g\ast f\right)\left(i\right)-\sum_{i=2}^{n}g\left(i\right)S\left(\frac ni\right)$
如果狄利克雷卷积的前缀和非常好算的话(比如化成了$\sum_{i=1}^{n}i$这样的),就可以$O\left(1\right)$求出来,然后记忆化搜索了
但是这样有一个问题:我一直往下记忆化,效率不还是$O\left(n\right)$的吗?
的确,但是我们有一个好东西叫做线性筛
假设我们把一部分的$f$先筛出来,然后再把这一部分的$S$求出来,到了比某一个范围小的时候不就可以$O\left(1\right)$返回了吗?
根据杜教的证明(因为这东西太复杂了......懒得写上来,记住就好),当我们筛出来$O\left(n^\frac{2}{3}\right)$个$S$,剩下的记忆化时,我们的记忆化搜索时间效率降到$O\left(n^\frac{2}{3}\right)$
因此总的时间效率就是$O\left(n^\frac{2}{3}\right)$
为了加深理解,我们看一道例题:
这里就是一个选取$g$函数的很好的例子
另外一个例子:BZOJ4916
很多时候杜教筛会和莫比乌斯反演结合应用,也就是先反演出来,然后杜教筛一个和$\mu$有关的积性函数(不一定是$\mu$),以达成数论分块的目的
总结
杜教筛以及莫比乌斯反演的内容其实到这里就结束了,因为它们俩本身的知识性内容也不多,但是一定要确保自己理解了上面写的每一句话、每一个公式
八道例题也最好都看一遍,因为这些都是经典的以及常用的方法在题目中的体现
最后,想要学好数论方面的知识是比较难的,因为数论中的内容错综复杂,一个知识点往往和数个知识点之间有连接关系
但是学好数论必不可少的、也是方便快捷的一条路,就是认真推导
把每一个式子都在纸上写出来、理解它为什么能这么推、还有为什么要这么推
遇到题目的时候也要想一想:出题人想让我往哪个方向推导?我应该用什么方法靠近这个方向?
这样,学习数论的时候才不会感觉到无所适从,才能掌握信息竞赛中数论题目的精髓所在