写在前面
这篇博客用来记录一下我学习莫比乌斯反演的过程,以及我是如何理解它的。
期间参考了大量其他博客,这里列出表示感谢:
- 莫比乌斯反演 by OI-wiki
- 莫比乌斯反演-让我们从基础开始 by An_Account
- 莫比乌斯反演-从莫比乌斯到欧拉 by An_Account
- 莫比乌斯反演学习笔记 by LNRBHAW
- 莫比乌斯函数 by Grary
- 数论函数 - 莫比乌斯函数与莫比乌斯反演 - 基础杜教筛 by zhouzhendong
参考的博客包括但不限于以上这些,有些看过的博客忘记了(逃
另外,如果本篇博客涉及侵权,请您及时联系我修改,以免造成不必要的损失。
前置知识
学习莫比乌斯反演以前,需要先了解的一些前置知识。
积性函数
积性函数是数论中一个非常重要的概念,常常可以利用其性质来进行数论分块优化。
定义
若gcd(x,y)=1且f(xy)=f(x)f(y),则称函数f(x)为积性函数。
扩展:若对于任意(x,y)满足f(xy)=f(x)f(y),则称函数f(x)为完全积性函数。
性质
若f(x)和g(x)均为积性函数,则下列函数h(x)也为积性函数:
- h(x)=f(xp)
- h(x)=fp(x)
- h(x)=f(x)g(x)
- h(x)=d∣x∑f(d)g(dx)
所有的积性函数都可以用线性筛求。
其实4就是之后会提到的狄利克雷卷积。
常见的积性函数
- 单位函数:ε(n)=[n=1],也常写作ε
- 恒等函数:idk(n)=nk,id1(n)常写作id(n)
- 常数函数1(n)=1,常常直接用1代替
- 除数函数:σk(n)=d∣n∑dk,σ0(n)通常记为d(n),即常数函数,σ1(n)通常记为σ(n)
- 欧拉函数:φ(n)=i=1∑n[gcd(i,n)=1]
- 莫比乌斯函数: μ(d)=⎩⎪⎨⎪⎧1,(−1)k,0,d=0d=p1⋅p2…pk,∀pi=pjothers
本篇文章出现的所有[x]表示若x为真值则[x]为1,否则为0,且接下来的内容遇到以上函数,可以简写的将尽可能地用简写代替。
狄利克雷卷积
也叫狄利克雷乘积(Dirichlet product),是数论重要知识之一,也是推导、证明莫比乌斯反演的关键。
定义
定义两个数论函数f(n),g(n)的狄利克雷卷积为:
(f(n)∗g(n))(n)=d∣n∑f(d)g(dn)
(f(n)∗g(n))(n)常写作f∗g
注:数论函数指定义在N+上的函数,满足积性和加性性质。
另外,为了更方便地区分,本文所有f∗g代表狄利克里卷积,而普通乘法则会写成f⋅g或fg
性质
- 狄利克雷卷积满足交换律、结合律和分配律(前提是函数均满足加性)。
f∗g=g∗f
(f∗g)∗h=f∗(g∗h)
f∗(g+h)=f∗g+f∗h
- ε为狄利克雷卷积的幺元(单位元)。
∀f(x),x∈N+⟹f∗ε=ε∗f=f
-
若f(x)和g(x)均为积性函数,则f∗g也是积性函数,反之若f∗g和g(x)均为积性函数,则f(x)也是积性函数。
-
若g(x)是完全积性函数,且h(x)=f∗g,则f(x)=h∗(μ⋅g)
一些例子
- μ∗1=d∣n∑μ(d)=d∣n∑μ(dn)=1∗μ=ε
- 1∗1=d∣n∑1=d(n)
- μ∗id=d∣n∑d⋅μ(dn)=φ(n)
- φ∗1=d∣n∑φ(dn)=id(n)
莫比乌斯函数
定义
μ(d)=⎩⎪⎨⎪⎧1,(−1)k,0,d=0d=p1⋅p2…pk,∀pi=pjothers
性质
- μ是积性函数。
- d∣n∑μ(d)=ε
- d∣gcd(i,j)∑μ(d)=ε(gcd(i,j))=[gcd(i,j)=1]
- d∣n∑dμ(d)=nφ(n)
线性筛
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const int MAX_N = 1e6 + 10; bool vis[MAX_N]; int CNT, prime[MAX_N], mu[MAX_N];
void make_mobius() { memset(vis, false, sizeof(vis)); mu[1] = 1; CNT = 0; for(int i = 2; i < MAX_N; ++i) { if(!vis[i]) { prime[++CNT] = i; mu[i] = -1; } for(int j = 1; j <= CNT && i*prime[j] < MAX_N; ++j) { vis[i*prime[j]] = true; if(i % prime[j] == 0) { mu[i * prime[j]] = 0; break ; } else mu[i * prime[j]] = -mu[i]; } } }
|
莫比乌斯反演
定义
设f(n)、g(n)为两个数论函数,如果
f(n)=d∣n∑g(d)
那么有
g(n)=d∣n∑μ(d)f(dn)
根据狄利克雷卷积的性质,当然也可以
f(n)=n∣d∑g(d)⇒g(n)=n∣d∑μ(nd)f(d)
证明
其实第一个反演公式还蛮好证明的:
∵f(n)=d∣n∑g(d)
∴d∣n∑μ(d)f(dn)=d∣n∑μ(d)k∣dn∑g(k)
根据积性函数性质得
d∣n∑μ(d)k∣dn∑g(k)=d∣n∑g(d)k∣dn∑μ(k)
又
∵d∣n∑μ(d)=[n=1]⇒k∣dn∑μ(k)=[dn=1]
∴d∣n∑g(d)k∣dn∑μ(k)=d∣n∑g(d)⋅[n=d]=g(n)
同理可以证第二个反演公式,证毕。
不过利用狄利克雷卷积证明更快:
第一个反演公式可以转换为
f=g∗1⇒g=μ∗f
则有
μ∗f=μ∗g∗1=g∗(μ∗1)=g∗ε=g
证毕。
一些应用
了解了莫比乌斯函数及其反演以后,我们就可以来学习和推导一些东西。
简单例子:推导欧拉函数
假设让你求这样一个式子:
i=1∑n[gcd(i,n)=1],(1≤n≤107)
根据上面提到的莫比乌斯函数的性质3,可以将原式转化为
i=1∑nd∣gcd(i,n)∑μ(d)
当然这样还是不好求,我们需要转换思路,转而去枚举d,易知d∈[1,n],则可将上式化为
=d=1∑nμ(d)i=1∑n[d∣i]d=1∑nμ(d)⌊dn⌋
实际上这就是我们喜闻乐见的欧拉函数φ(n)。
简单例子扩展
假设现在让你求:
i=1∑nj=1∑m[gcd(i,j)=k],(1≤k≤n≤m≤105)
注意:从这里开始若下文的n、m没有特殊说明,都是这个量级。
看起来比简单例子难很多?实际上没有,我们依然可以用简单例子的思路。
当然,第一件事是将[gcd(i,j)=k]转换成[gcd(i,j)=1]
i=1∑⌊kn⌋j=1∑⌊km⌋[gcd(i,j)=1]
这一步应该很好理解吧?相当于i,j都除掉最大公因数k(逃
接下来的一顿操作就和之前一样了
===i=1∑⌊kn⌋j=1∑⌊km⌋[gcd(i,j)=1]i=1∑⌊kn⌋j=1∑⌊km⌋d∣gcd(i,j)∑μ(d)d=1∑⌊kn⌋μ(d)i=1∑⌊kn⌋[d∣i]j=1∑⌊km⌋[d∣j]d=1∑⌊kn⌋μ(d)⌊kdn⌋⌊kdm⌋
如果你看到这里能够理解,说明你对莫比乌斯函数已经有一定感觉了。
另一个简单例子:求最大公约数的和
再来求这样一个式子:
i=1∑ngcd(i,n)
有了前面莫比乌斯的套路,那我们我们就有了第一步——化gcd为虚无!
这里当然不能直接地将gcd转化为μ,我们需要借助φ的性质:
d∣n∑φ(d)=n⇒d∣gcd(i,n)∑φ(d)=gcd(i,n)
然后就成功将原式子转化成
i=1∑nd∣gcd(i,n)∑φ(d)
显而易见地可以用上前面的套路直接再转化成
d=1∑nφ(d)i=1∑n[d∣i]⇒d=1∑nφ(d)⌊dn⌋
喜闻乐见地,我们得到了一个和第一个简单例子类似的式子。
自然地,对于这个式子也有一定的扩展,推导方式和之前类似,这里直接给结果。
i=1∑nj=1∑mgcd(i,j)=d=1∑nφ(d)⌊dn⌋⌊dm⌋
扩展:求最小公倍数的和
i=1∑nlcm(i,n)⇒i=1∑ngcd(i,n)i⋅n
易知gcd(a,b)=gcd(b−a,b),则上式可化为
=21⋅(i=1∑n−1gcd(i,n)i⋅n+i=1∑n−1gcd(n−i,n)(n−i)⋅n)+n21⋅i=1∑n−1gcd(i,n)n2+n
有了之前的经验,我们就要想办法把gcd(i,n)相同的项合并,于是我们枚举d=gcd(i,n),易知共有φ(dn)个。则上式可化为
21⋅d<n,d∣n∑dn2⋅φ(dn)+n
再令d′=dn得
2n⋅d′>1,d′∣n∑d′φ(d′)+n
设g(n)=d′>1,d′∣n∑d′φ(d′),易知g(n)是积性函数,可以利用其性质进行线性筛。
这里用了一种巧妙地方式化简,如果用常规的莫比乌斯反演套路推导:
===i=1∑nlcm(i,n)=i=1∑ngcd(i,n)i⋅nn⋅d∣n∑d1⋅i=1∑n[gcd(i,n)=d]⋅in⋅d∣n∑d1⋅i=1∑dn[gcd(i,dn)=1]⋅i⋅dn⋅d∣n∑i=1∑dn[gcd(i,dn)=1]⋅i
根据欧拉函数的性质有gcd(i,n)=1∑ni=2n⋅φ(n)(n>1),上式可化为
n⋅d∣n∑2dn⋅φ(dn)
同样令d′=dn得
n⋅d′∣n∑2d′φ(d′)
推导到这里其实可以发现一个问题:我们会在计算过程中不小心忽略了d=n即d′=1的情况,所以我们最后需要再加上lcm(n,n)=n,即最终答案为:
n⋅d′>1,d′∣n∑2d′φ(d′)+n
和我们上面巧妙推导方式的结果是一样的。
有些文章会写成
2n⋅⎝⎛d′∣n∑d′φ(d′)+1⎠⎞
本质上是一样的,原因就在于n=1时,gcd(i,n)=1∑ni=1。
再扩展:二维最小公倍数求和
i=1∑nj=1∑mlcm(i,j)⇒i=1∑nj=1∑mgcd(i,j)i⋅j
这里显然不能再用上面非传统的化简思路,还得用回常规套路:
=====i=1∑nj=1∑md=1∑ndi⋅j⋅[gcd(i,j)=d]d=1∑ni=1∑⌊dn⌋j=1∑⌊dm⌋di⋅j⋅d2⋅[gcd(i,j)=1]d=1∑ndi=1∑⌊dn⌋j=1∑⌊dm⌋i⋅j⋅[gcd(i,j)=1]d=1∑ndi=1∑⌊dn⌋j=1∑⌊dm⌋i⋅j⋅k∣gcd(i,j)∑μ(k)d=1∑nd⋅k=1∑⌊dn⌋μ(k)⋅k2⋅i=1∑⌊dkn⌋j=1∑⌊dkm⌋i⋅j
到这一步,已经是一个朴素都能将时间复杂度控制在O(n⋅log2n)的优化了,甚至进行两步分块,可以将时间复杂度降到O(n)。但是对于一些恶心的题目,仍然不够用,我们还可以再进一步优化。
持续更新中……