简介
当一个函数
f(x)
f
(
x
)
计算十分复杂时,如果方便计算出它的倍数的和,或因数的和
g(x)
g
(
x
)
,可先计算出
g(x)
g
(
x
)
,再通过莫比乌斯反演计算出
f(x)
f
(
x
)
。
例子:
g(1)=f(1)
g
(
1
)
=
f
(
1
)
g(2)=f(1)+f(2)
g
(
2
)
=
f
(
1
)
+
f
(
2
)
g(3)=f(1)+f(3)
g
(
3
)
=
f
(
1
)
+
f
(
3
)
g(4)=f(1)+f(2)+f(4)
g
(
4
)
=
f
(
1
)
+
f
(
2
)
+
f
(
4
)
g(5)=f(1)+f(5)
g
(
5
)
=
f
(
1
)
+
f
(
5
)
g(6)=f(1)+f(2)+f(3)+f(6)
g
(
6
)
=
f
(
1
)
+
f
(
2
)
+
f
(
3
)
+
f
(
6
)
g(7)=f(1)+f(7)
g
(
7
)
=
f
(
1
)
+
f
(
7
)
g(8)=f(1)+f(2)+f(4)+f(8)
g
(
8
)
=
f
(
1
)
+
f
(
2
)
+
f
(
4
)
+
f
(
8
)
莫比乌斯反演:
将上面的例子倒回来算
f(1)=g(1)
f
(
1
)
=
g
(
1
)
f(2)=g(2)−g(1)
f
(
2
)
=
g
(
2
)
−
g
(
1
)
f(3)=g(3)−g(1)
f
(
3
)
=
g
(
3
)
−
g
(
1
)
f(4)=g(4)−g(2)
f
(
4
)
=
g
(
4
)
−
g
(
2
)
f(5)=g(5)−g(1)
f
(
5
)
=
g
(
5
)
−
g
(
1
)
f(6)=g(6)−g(3)−g(2)+g(1)
f
(
6
)
=
g
(
6
)
−
g
(
3
)
−
g
(
2
)
+
g
(
1
)
f(7)=g(7)−g(1)
f
(
7
)
=
g
(
7
)
−
g
(
1
)
f(8)=g(8)−g(4)
f
(
8
)
=
g
(
8
)
−
g
(
4
)
反演公式(待证):
莫比乌斯函数
这里有个神奇的东西:
μ(i)
μ
(
i
)
是莫比乌斯函数:
μ(1)=1
μ
(
1
)
=
1
μ(2)=−1
μ
(
2
)
=
−
1
μ(3)=−1
μ
(
3
)
=
−
1
μ(4)=0
μ
(
4
)
=
0
……
定义如下:
- μ(1)=1 μ ( 1 ) = 1
- 当x分解质因数后,所有质因数的指数为1,那么 μ(x)=(−1)k μ ( x ) = ( − 1 ) k (k为将x分解质因数后,质因数的个数)
- 当x分解质因数后,有质因数的指数>1,那么
μ(x)=0
μ
(
x
)
=
0
(为什么这样定义:实际上是容斥原理,有些问题,先加上含一个质因子的所有数,减去含两个质因子的所有数,加上含三个质因子的所有数……正好使用莫比乌斯函数,方便快捷!)
性质
- ∑d|nμ(d)=0(n>1)或1(n=1) ∑ d | n μ ( d ) = 0 ( n > 1 ) 或 1 ( n = 1 )
证明:将n分解 n=pa11pa22pa33...pakk n = p 1 a 1 p 2 a 2 p 3 a 3 . . . p k a k
根据定义,只有在k个p里取,每个p指数为1时才有效,取奇数个为-1,去偶数个为1
∴∑d|nμ(d)=C0k−C1k+C2k−...+(−1)kCkk=∑i=0n(−1)iCin=0 ∑ d | n μ ( d ) = C k 0 − C k 1 + C k 2 − . . . + ( − 1 ) k C k k = ∑ i = 0 n ( − 1 ) i C n i = 0(二项式定理,当x=1,y=-1, (x+y)n= ( x + y ) n = 上面那一坨) 积性函数:
μ(xy)=μ(x)μ(y) μ ( x y ) = μ ( x ) μ ( y )
筛法求莫比乌斯函数
所以可以用线性筛的方法筛出莫比乌斯函数:
mu[1]=1;
for(i=2;i<=n;i++)
{
if(!not_prime[i])
{
prime[++tot]=i;
mu[i]=-1;
}
for(j=1;prime[j]*i<=n;j++)
{
not_prime[prime[j]*i]=1;
if(i%prime[j]==0)
{
mu[prime[j]*i]=0;
break;
}
mu[prime[j]*i]=-mu[i];
}
}
反演函数证明
现在倒回来证明开始那个反演函数:
证明:
根据性质,当 xj=1 x j = 1 时 ∑i|xjμ(i)=1 ∑ i | x j μ ( i ) = 1 ,其他时候等于0.
分块优化
实际题目中,直接跑莫比乌斯反演暴力一般是要超时的。。。(尴尬,,ԾㅂԾ,,),一般都要加优化。主要有一个分块思想。
很多题都是这种情况(一般涉及gcd),绿色代表
nkd
n
k
d
相等,蓝色部分代表
mkd
m
k
d
相等,红色部分代表两个都相等。这样,再同一个红色块的就可以一次计算,所以我们需要预处理
μ(d)
μ
(
d
)
的前缀和,用last=min(n/(n/d),m/(m/d));计算出当前红块的结尾位置,就可以把时间优化到
O(n−−√+m−−√)
O
(
n
+
m
)
。
if(n>m) swap(n,m);
for(i=1;i<=n;i=last+1)
{
last=min(n/(n/i),m/(m/i));
re+=(n/i)*(m/i)*(sum[last]-sum[i-1]);
}
return re;