莫比乌斯反演
1. 定义
对于一个定义在非负整数上的函数 f(n) f ( n ) ,定义函数 F(n) F ( n ) 。
那么有如下结论:
其中:
(1)若d=1,则μ(d)=1
(
1
)
若
d
=
1
,
则
μ
(
d
)
=
1
(2)若d=p1p2p3p4...pk,即d有k个互异的质因子μ(d)=(−1)k
(
2
)
若
d
=
p
1
p
2
p
3
p
4
.
.
.
p
k
,
即
d
有
k
个
互
异
的
质
因
子
μ
(
d
)
=
(
−
1
)
k
(3)其他情况下μ(d)=0
(
3
)
其
他
情
况
下
μ
(
d
)
=
0
2.莫比乌斯函数的性质&证明
性质1:
证明:
n=1时显然成立;
n>1时:
设n=pa11pa22pa33...pakk,n1=p1p2p3...pk 设 n = p 1 a 1 p 2 a 2 p 3 a 3 . . . p k a k , n 1 = p 1 p 2 p 3 . . . p k
设d,d|n1所以d|n,若d包含多个相同质因子,则μ(d)无贡献,反之有贡献 设 d , d | n 1 所 以 d | n , 若 d 包 含 多 个 相 同 质 因 子 , 则 μ ( d ) 无 贡 献 , 反 之 有 贡 献
那么易知
所以μ(d)的值与取的质因子个数有关,即 所 以 μ ( d ) 的 值 与 取 的 质 因 子 个 数 有 关 , 即
由二项式定理:
取 a=−1,b=1,则 a = − 1 , b = 1 , 则
性质2:
莫比乌斯反演定理的证明:
最后两步的解释:
我们枚举d’,因为
d′|nd,所以d′|n,令d′=knd,那么d=knd′,即d|nd′,然后当且仅当d′=n时
d
′
|
n
d
,
所
以
d
′
|
n
,
令
d
′
=
k
n
d
,
那
么
d
=
k
n
d
′
,
即
d
|
n
d
′
,
然
后
当
且
仅
当
d
′
=
n
时
∑nd′d|nd′μ(d)=1,最后结果为f(n)
∑
d
|
n
d
′
n
d
′
μ
(
d
)
=
1
,
最
后
结
果
为
f
(
n
)
3.莫比乌斯函数的筛法
线性筛法:
int pri[N];int cnt=0;
bool vis[N];
int mu[N];
inline void prepare()//线性筛法求 mu(d)
{
vis[1]=1;
for(register int i=2;i<=n;i++)
{
if(!vis[i]) {pri[++cnt]=u;mu[i]=-1;}
for(register int j=1;j<=cnt&&((1ll*pri[j]*i)<=n);j++)
{
vis[pri[j]*i]=1;
if(i%pri[j]==0) {mu[i*pri[j]]=0;break;}//此时有两个相同因子
mu[i*pri[j]]=-mu[i];//新加一个相异质数;
}
}
return ;
}
4.应用
注:以下除法未说明均为向下取整。
其实莫比乌斯反演还有另一种描述:
证明类似:
首先知道若 nk|d, n k | d , 那么 n|d,k|d n | d , k | d 。
∑nn|dμ(dn)F(d)=∑+∞k=1μ(k)F(nk)=∑+∞k=1μ(k)∑nk|d′f(d′)
∑
n
|
d
n
μ
(
d
n
)
F
(
d
)
=
∑
k
=
1
+
∞
μ
(
k
)
F
(
n
k
)
=
∑
k
=
1
+
∞
μ
(
k
)
∑
n
k
|
d
′
f
(
d
′
)
=∑n|df(d)∑k|ndμ(k)=f(n)当且仅当d=n时∑k|ndμ(k)=1
=
∑
n
|
d
f
(
d
)
∑
k
|
n
d
μ
(
k
)
=
f
(
n
)
当
且
仅
当
d
=
n
时
∑
k
|
n
d
μ
(
k
)
=
1
一般都用这种
担心d会无限增大?F(d)这时就会没贡献了
1.一道简单例题:
求i从1到n,j从1到m的i,j互质的对数
求
i
从
1
到
n
,
j
从
1
到
m
的
i
,
j
互
质
的
对
数
那么就设f(x)为n,m内gcd=x的对数,F(x)=∑x|df(dx) 那 么 就 设 f ( x ) 为 n , m 内 g c d = x 的 对 数 , F ( x ) = ∑ x | d f ( d x )
那么推知F(x)表示n,m内x|gcd的对数, 那 么 推 知 F ( x ) 表 示 n , m 内 x | g c d 的 对 数 ,
现在要求
f(1)
f
(
1
)
,套用公式就是:
f(1)=∑min(n,m)1|dμ(d1)F(d)
f
(
1
)
=
∑
1
|
d
m
i
n
(
n
,
m
)
μ
(
d
1
)
F
(
d
)
即
f(1)=∑min(n,m)d=1μ(d)F(d)
f
(
1
)
=
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
F
(
d
)
易知
F(d)=nd∗md,即为gcd是d的倍数的对数
F
(
d
)
=
n
d
∗
m
d
,
即
为
g
c
d
是
d
的
倍
数
的
对
数
那么
f(1)=∑min(n,m)d=1μ(d)nd∗md
f
(
1
)
=
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
n
d
∗
m
d
这样我们其实也可以轻松求出
gcd=k
g
c
d
=
k
的对数,因为
n,m
n
,
m
中
gcd=k
g
c
d
=
k
的数的对数即为
nd,md中,
n
d
,
m
d
中
,
gcd=1
g
c
d
=
1
的数的对数。
所以就是:
f(k)=∑min(n,m)k|dμ(dk)F(d)=∑min(n,m)k|dμ(dk)nd∗md
f
(
k
)
=
∑
k
|
d
m
i
n
(
n
,
m
)
μ
(
d
k
)
F
(
d
)
=
∑
k
|
d
m
i
n
(
n
,
m
)
μ
(
d
k
)
n
d
∗
m
d
=∑min(nk,mk)d=1μ(d)nkd∗mkd
=
∑
d
=
1
m
i
n
(
n
k
,
m
k
)
μ
(
d
)
n
k
d
∗
m
k
d
(可以理解为枚举了
dk),令n′=nk,m′=mk
d
k
)
,
令
n
′
=
n
k
,
m
′
=
m
k
=∑min(n′,m′)d=1n′d∗m′d∗μ(d)
=
∑
d
=
1
m
i
n
(
n
′
,
m
′
)
n
′
d
∗
m
′
d
∗
μ
(
d
)
然后还可以对除法进行分块,并求出
μ(d)
μ
(
d
)
的前缀和,即可达到每次
O(n‾√)
O
(
n
)
的回答
虽然预处理有O(n)
贴个代码 LupguP2522 [HAOI2011]Problem b
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
inline int read()
{
int x=0;char ch=getchar();int t=1;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
return x*t;
}
const int N=5e4+10;
int mu[N];
typedef long long ll;
int pri[N];int cnt;bool vis[N];
inline void prepara()
{
mu[1]=1;vis[1]=1;
for(register int i=2;i<=N;i++)
{
if(!vis[i]) {pri[++cnt]=i;mu[i]=-1;}
for(register int j=1;j<=cnt&&(1ll*pri[j]*i<N);j++)
{
register int x=i*pri[j];
vis[x]=1;
if(i%pri[j]==0) {mu[x]=0;break;}
mu[x]=-mu[i];
}
}
for(register int i=1;i<N;++i) mu[i]+=mu[i-1];
}
inline ll calc(int a,int b,int c)
{
if(a>b) swap(a,b);
if(a==0) return 0;
a/=c;b/=c;
register ll res=0;
register int l,r;
for(l=1;l<=a;l=r+1)
{
r=min(a/(a/l),b/(b/l));
if(r>a) r=a;
res+=1ll*(mu[r]-mu[l-1])*(a/l)*(b/l);
}
return res;
}
int main()
{
prepara();
int T=read();
while(T--)
{
register int a=read(),b=read(),c=read(),d=read(),e=read();
if(e==0) {puts("0");continue;}
register ll ans1=calc(b,d,e)-calc(a-1,d,e);
register ll ans2=calc(b,c-1,e)-calc(a-1,c-1,e);
//这题还要容斥一波
printf("%lld\n",ans1-ans2);
}
}
2.再来几道题
3.小结:
由上面几道题可以看出:
常用套路:
○1.过硬的推式子能力,灵活变更枚举数的顺序
○2.根据式子列出相关函数并利用莫比乌斯反演公式进行求解
○3.利用莫比乌斯函数的性质对式子进行化简,变形