版权声明:本文为hzy原创文章,未经博主允许不可随意转载。 https://blog.csdn.net/Binary_Heap/article/details/81840564
前言
(今天入坑莫比乌斯反演,感觉全都是不可做题..)
莫比乌斯反演属于数论中较难的部分吧,做这种题一般长片的推导,化简,最后用枚举或者整除分块等求出答案(我做题少只见过这些).
下面要引入一些东西做铺垫.
数论函数与积性函数
首先定义数论函数
f(x)
:定义域和值域都是整数的函数.
定义积性函数:
∀a,b,gcd(a,b)=1
,
f(ab)=f(a)f(b)
,称
f
为积性函数
常见的积性函数有欧拉函数、莫比乌斯函数、除数函数等(这个不需要展开了解).
狄利克雷卷积
狄利克雷卷积(
Dirichlet
)卷积的定义如下:
f,g
是两个数论函数,他们的
Dirichlet
卷积为:
(f∗g)(n)=Σd|nf(d)g(nd)
它满足交换率,因为
d
正序取遍约数时
nd
也逆序取遍约数
它也满足结合律,分配率,根据定义推一推都比较好证明.
Dirichlet
卷积的小性质:两个积性函数卷起来还是积性函数.
莫比乌斯函数
下面定义莫比乌斯函数
μ
.
一个数
n
分解成
Πpcii
.
若存在
ci>1
,
μ(n)=0
否则
μ(n)=(−1)k,k
为本质不同的质因子个数
可以使用线性筛预处理:
其中
mu(i)
表示
μ(i)
,
flag
为素数标记,
pr
为素数表
void Init(int n) {
memset(flag, 1, sizeof flag); flag[1] = false;
cnt = 0; mu[1] = 1;
for(int i = 2; i <= n; i ++) {
if(flag[i]) {
pr[++ cnt] = i;
mu[i] = -1;
}
for(int j = 1; j <= cnt && pr[j] * i <= n; j ++) {
flag[ i * pr[j] ] = false;
if(i % pr[j] == 0) {
mu[ i * pr[j] ] = 0;
break ;
}
mu[ i * pr[j] ] = - mu[i];
}
}
}
莫比乌斯函数有什么用呢?我们需要引入一个不错的结论:
e(n)=∑d|nμ(d)
先来介绍一下
e
吧,
e
表示狄利克雷卷积的单位元,即
e∗f=f
,显然这个
e(n)
应该为
[n==1]
,就是说
n
为
1
时值是
1
,否则值为
0
。这不难证明,套上卷积的定义即可.
好了,介绍完了,来证明一下这个式子吧.
把
n
表示成
∏ki=1pcii
,令
n′=∏ki=1pi
,根据
μ
函数的定义,指数超过
1
那么这个数产生的贡献为
0
,可以直接忽略.所以
∑d|nμ(d)=∑d|n′μ(d)
。
∑d|nμ(d)=∑d|n′μ(d)=∑ki=1Cik(−1)i=[k==0]
有
0
个质因子的时候等于
1
,其他时候等于
0
.与
e
是完全相同的.就证出来了.
几个函数
e
是单位元,
1
是
f(x)=1
的常函数,
μ
是莫比乌斯函数,
ϕ
为欧拉函数,
id
为
f(i)=i
的函数.
他们卷起来有一些神奇的性质,下面两个性质可能比较重要,之后应该会用.
-
ϕ∗1=id
-
id∗μ=ϕ
证明应该质因数分解一下就行,不会(逃
莫比乌斯反演
说了半天,终于说到了本篇博客要讲的知识,莫比乌斯反演(
MobiusInversion
).
f(n),g(n)
是两个数论函数.
如果有
f(n)=∑d|ng(d)
那么有
g(n)=∑d|nμ(d)f(nd)
即
g=μ∗f
我对莫比乌斯反演的作用的理解:
原来是用
g
来表示
f
,反演过后是用
f
来表示
g
.这个过程需要借助莫比乌斯函数,所以称莫比乌斯反演.
证明:我又不会(再逃
一种经典模型
给定
f,n,m
,求
∑ni=1∑mj=1f(gcd(i,j))
.
T
组询问,
T≤104,n,m≤106
.
解法:
不妨设
n≤m
,枚举
d=gcd(i,j)
:
∑i=1n∑j=1mf(gcd(i,j))
=∑d=1n∑i=1n∑j=1mf(d)[gcd(i,j)==d]
令
i=i′d,j=j′d
,枚举
i′,j′
:
=∑d=1n∑i′=1⌊nd⌋∑j′=1⌊md⌋f(d)[gcd(i′,j′)==1]
用
e
代替
[gcd(i′,j′)==1]
:
=∑d=1n∑i′=1⌊nd⌋∑j′=1⌊md⌋f(d)e(gcd(i′,j′))
用之前的结论展开
e
函数:
=∑d=1n∑i′=1⌊nd⌋∑j′=1⌊md⌋f(d)∑d′|gcd(i′,j′)μ(d′)
d|gcd(i′,j′)
意味着
d|i′
并且
d|j′
:
=∑d=1n∑i′=1⌊nd⌋∑j′=1⌊md⌋f(d)∑d′|i′,d′|j′μ(d′)
变换枚举顺序,将
d′
提前:
=∑d=1n∑d′=1nμ(d′)∑i′′=1⌊ndd′⌋∑j′′=1⌊mdd′⌋f(d)
=∑d=1n∑d′=1nμ(d′)⌊ndd′⌋⌊mdd′⌋f(d)
令
g(k)=∑d|kμ(k)f(kd)
,
枚举乘积
k=dd′
,原式化为:
∑k=1ng(k)⌊nk⌋⌊mk⌋
根据定义式
O(nlogn)
暴力预处理出
g
,再
O(n−−√)
地回答每个询问,使用整除分块即可.
对于
f
有特殊性质的情况,有可能可以线性筛
O(n)
预处理.