本篇文章主要为莫比乌斯反演的基本讲解,附以一小部分的狄利克雷卷积辅助理解。
文章目录
莫比乌斯反演
正片开始
关于反演
顾名思义,反演就是反向演变,举个栗子,若有 F ( n ) = k ⋅ f ( n ) F(n)=k\cdot f(n) F(n)=k⋅f(n),我们能够推出 f ( n ) = F ( n ) k f(n)=\dfrac {F(n)} k f(n)=kF(n),这就是反演。
莫比乌斯函数
定义
μ ( n ) = { 1 n = 1 ( − 1 ) k n = p 1 p 2 … p k ( p i ∈ P ) 0 p 2 ∣ n ( p ∈ P ) \mu(n)=\begin{cases}1&n=1\\(-1)^k&n=p_1p_2\dots p_k(p_i\in P)\\0&p^2|n(p\in P)\end{cases} μ(n)=⎩ ⎨ ⎧1(−1)k0n=1n=p1p2…pk(pi∈P)p2∣n(p∈P)
性质
∑
d
∣
n
μ
(
d
)
=
[
n
=
1
]
\sum\limits_{d|n}\mu(d)=[n=1]
d∣n∑μ(d)=[n=1]
证明:
当
n
=
1
n=1
n=1时显然。
考虑
μ
(
d
)
\mu(d)
μ(d)的贡献。
只有当
d
d
d中的质因子都只出现一次时,
μ
(
d
)
\mu(d)
μ(d)才对和式有贡献。
问题变成了在
n
n
n的质因子中选择
k
k
k个,
k
k
k为奇数则贡献为
−
1
-1
−1,
k
k
k为偶数则贡献为
1
1
1.
设
n
n
n中有
m
m
m种不同的质因子。
∑
d
∣
n
μ
(
d
)
=
∑
j
=
0
m
(
−
1
)
j
(
m
j
)
\sum\limits_{d|n}\mu(d)=\sum\limits_{j=0}^m(-1)^j\begin{pmatrix}m\\j\end{pmatrix}
d∣n∑μ(d)=j=0∑m(−1)j(mj)
(
m
j
)
\begin{pmatrix}m\\j\end{pmatrix}
(mj)表示在
m
m
m个不同的数中选取
j
j
j个数的方案数,等价于
C
m
j
C^j_m
Cmj.
根据二项式定理
(
x
+
y
)
n
=
∑
i
=
0
n
(
n
i
)
x
i
y
n
−
i
(x+y)^n=\sum\limits_{i=0}^n\begin{pmatrix}n\\i\end{pmatrix}x^iy^{n-i}
(x+y)n=i=0∑n(ni)xiyn−i,我们令
x
=
−
1
,
y
=
1
x=-1,y=1
x=−1,y=1,就可以发现右边的和式等于
∑
j
=
0
m
(
−
1
)
j
(
m
j
)
\sum\limits_{j=0}^m(-1)^j\begin{pmatrix}m\\j\end{pmatrix}
j=0∑m(−1)j(mj),所以有
∑
d
∣
n
μ
(
d
)
=
∑
j
=
0
m
(
−
1
)
j
(
m
j
)
=
(
1
−
1
)
m
=
0
\sum\limits_{d|n}\mu(d)=\sum\limits_{j=0}^m(-1)^j\begin{pmatrix}m\\j\end{pmatrix}=(1-1)^m=0
d∣n∑μ(d)=j=0∑m(−1)j(mj)=(1−1)m=0
得证。
这就是说,当 n = 1 n=1 n=1时 ∑ d ∣ n μ ( d ) = 1 \sum\limits_{d|n}\mu(d)=1 d∣n∑μ(d)=1,否则 ∑ d ∣ n μ ( d ) = 0 \sum\limits_{d|n}\mu(d)=0 d∣n∑μ(d)=0.
莫比乌斯反演公式
公式1
若
F
(
n
)
=
∑
d
∣
n
f
(
d
)
F(n)=\sum\limits_{d|n}f(d)
F(n)=d∣n∑f(d),则
f
(
n
)
=
∑
d
∣
n
μ
(
d
)
F
(
n
d
)
f(n)=\sum\limits_{d|n}\mu(d)F(\dfrac n d)
f(n)=d∣n∑μ(d)F(dn)
证明:
∑
d
∣
n
μ
(
d
)
F
(
n
d
)
=
∑
d
∣
n
μ
(
d
)
∑
p
∣
n
d
f
(
p
)
\sum\limits_{d|n}\mu(d)F(\dfrac n d)=\sum\limits_{d|n}\mu(d)\sum\limits_{p|\frac n d}f(p)
d∣n∑μ(d)F(dn)=d∣n∑μ(d)p∣dn∑f(p)
注意此时的运算顺序是
∑
d
∣
n
(
μ
(
d
)
∑
p
∣
n
d
f
(
p
)
)
\sum\limits_{d|n}(\mu(d)\sum\limits_{p|\frac n d}f(p))
d∣n∑(μ(d)p∣dn∑f(p))
这时候,我们可以手玩这个式子,来寻找规律。
我们让
n
=
6
n=6
n=6.
∑
d
∣
n
μ
(
d
)
∑
p
∣
n
d
f
(
p
)
=
∑
d
∣
6
μ
(
d
)
∑
p
∣
6
d
f
(
p
)
=
μ
(
1
)
×
(
f
(
1
)
+
f
(
2
)
+
f
(
3
)
+
f
(
6
)
)
+
μ
(
2
)
×
(
f
(
1
)
+
f
(
3
)
)
+
μ
(
3
)
×
(
f
(
1
)
+
f
(
2
)
)
+
μ
(
6
)
×
f
(
1
)
=
f
(
1
)
×
(
μ
(
1
)
+
μ
(
2
)
+
μ
(
3
)
+
μ
(
6
)
)
+
f
(
2
)
×
(
μ
(
1
)
+
μ
(
3
)
)
+
f
(
3
)
×
(
μ
(
1
)
+
μ
(
2
)
)
+
f
(
6
)
×
μ
(
1
)
=
∑
d
∣
6
f
(
d
)
∑
p
∣
6
d
μ
(
p
)
=
∑
d
∣
n
f
(
d
)
∑
p
∣
n
d
μ
(
p
)
\sum\limits_{d|n}\mu(d)\sum\limits_{p|\frac n d}f(p)\\=\sum\limits_{d|6}\mu(d)\sum\limits_{p|\frac 6 d}f(p)\\=\mu(1)\times (f(1)+f(2)+f(3)+f(6))\\\space+\mu(2)\times (f(1)+f(3))\\\space+\mu(3)\times (f(1)+f(2))\\\space+\mu(6)\times f(1)\\=f(1)\times (\mu(1)+\mu(2)+\mu(3)+\mu(6))\\\space+f(2)\times (\mu(1)+\mu(3))\\\space+f(3)\times (\mu(1)+\mu(2))\\\space +f(6)\times \mu(1)\\=\sum\limits_{d|6}f(d)\sum\limits_{p|{\frac 6 d}}\mu(p)\\=\sum\limits_{d|n}f(d)\sum\limits_{p|{\frac n d}}\mu(p)
d∣n∑μ(d)p∣dn∑f(p)=d∣6∑μ(d)p∣d6∑f(p)=μ(1)×(f(1)+f(2)+f(3)+f(6)) +μ(2)×(f(1)+f(3)) +μ(3)×(f(1)+f(2)) +μ(6)×f(1)=f(1)×(μ(1)+μ(2)+μ(3)+μ(6)) +f(2)×(μ(1)+μ(3)) +f(3)×(μ(1)+μ(2)) +f(6)×μ(1)=d∣6∑f(d)p∣d6∑μ(p)=d∣n∑f(d)p∣dn∑μ(p)
感性证明
这貌似不是巧合,其中肯定有什么规律。
思考为什么有
∑
d
∣
n
μ
(
d
)
∑
p
∣
n
d
f
(
p
)
=
∑
p
∣
n
f
(
p
)
∑
d
∣
n
p
μ
(
d
)
\sum\limits_{d|n}\mu(d)\sum\limits_{p|\frac n d}f(p)=\sum\limits_{p|n}f(p)\sum\limits_{d|{\frac n p}}\mu(d)
d∣n∑μ(d)p∣dn∑f(p)=p∣n∑f(p)d∣pn∑μ(d)
观察原式的枚举变量,容易发现
p
d
∣
n
pd|n
pd∣n,且
p
∣
n
,
d
∣
n
p|n,d|n
p∣n,d∣n
原式可以理解为枚举
μ
(
d
)
\mu(d)
μ(d),计算出现了多少个
μ
(
d
)
\mu(d)
μ(d)
而转化后的式子是枚举
f
(
p
)
f(p)
f(p),计算出现了多少个
f
(
p
)
f(p)
f(p)
那么有哪些
μ
\mu
μ值对
f
(
p
)
f(p)
f(p)有贡献呢?
换句话说,哪些
μ
\mu
μ值的和才是
f
(
p
)
f(p)
f(p)的系数呢?
因为
p
d
∣
n
pd|n
pd∣n,所以
d
∣
n
p
d|\dfrac n p
d∣pn. 满足这条性质的
μ
(
d
)
\mu(d)
μ(d)值之和就是
f
(
p
)
f(p)
f(p)的系数。
于是完成证明
∑
d
∣
n
μ
(
d
)
F
(
n
d
)
=
∑
p
∣
n
f
(
p
)
∑
d
∣
n
p
μ
(
d
)
\sum\limits_{d|n}\mu(d)F(\dfrac n d)=\sum\limits_{p|n}f(p)\sum\limits_{d|{\frac n p}}\mu(d)
d∣n∑μ(d)F(dn)=p∣n∑f(p)d∣pn∑μ(d)
根据莫比乌斯函数的性质,只有当
n
p
=
1
\dfrac n p=1
pn=1时,
f
(
p
)
∑
d
∣
n
p
μ
(
d
)
f(p)\sum\limits_{d|{\frac n p}}\mu(d)
f(p)d∣pn∑μ(d) 才不为
0
0
0,因为
∑
d
∣
n
p
μ
(
d
)
=
[
n
p
=
1
]
\sum\limits_{d|{\frac n p}}\mu(d)=[\dfrac n p=1]
d∣pn∑μ(d)=[pn=1].
此时
n
=
p
n=p
n=p.
也就是只有在
p
=
n
p=n
p=n时才会对
∑
p
∣
n
f
(
p
)
∑
d
∣
n
p
μ
(
d
)
\sum\limits_{p|n}f(p)\sum\limits_{d|{\frac n p}}\mu(d)
p∣n∑f(p)d∣pn∑μ(d)这个式子产生贡献。
所以
∑
p
∣
n
f
(
p
)
∑
d
∣
n
p
μ
(
d
)
=
f
(
n
)
\sum\limits_{p|n}f(p)\sum\limits_{d|{\frac n p}}\mu(d)=f(n)
p∣n∑f(p)d∣pn∑μ(d)=f(n).
于是得证。
公式2
若
F
(
n
)
=
∑
n
∣
d
f
(
d
)
F(n)=\sum\limits_{n|d}f(d)
F(n)=n∣d∑f(d),则
f
(
n
)
=
∑
n
∣
d
μ
(
d
n
)
F
(
d
)
f(n)=\sum\limits_{n|d}\mu(\dfrac d n)F(d)
f(n)=n∣d∑μ(nd)F(d)
证明:
思路同上,稍复杂。
∑
n
∣
d
μ
(
d
n
)
F
(
d
)
=
∑
n
∣
d
μ
(
d
n
)
∑
d
∣
p
f
(
p
)
\sum\limits_{n|d}\mu(\dfrac d n)F(d)=\sum\limits_{n|d}\mu(\dfrac d n)\sum\limits_{d|p}f(p)
n∣d∑μ(nd)F(d)=n∣d∑μ(nd)d∣p∑f(p)
仍然可以手玩
n
=
6
n=6
n=6的栗子,需要注意的是这里的项数有无限个。
手玩过程略,以下是理论简单证明。
已知
n
∣
d
∣
p
n|d|p
n∣d∣p,设
d
=
k
n
d=kn
d=kn,显然
k
n
∣
p
kn|p
kn∣p.
∑
n
∣
d
μ
(
d
n
)
∑
d
∣
p
f
(
p
)
=
∑
k
=
1
∞
μ
(
k
)
∑
k
n
∣
p
f
(
p
)
\sum\limits_{n|d}\mu(\dfrac d n)\sum\limits_{d|p}f(p)=\sum\limits_{k=1}^\infin\mu(k)\sum\limits_{kn|p}f(p)
n∣d∑μ(nd)d∣p∑f(p)=k=1∑∞μ(k)kn∣p∑f(p)
考虑
f
(
p
)
f(p)
f(p)的系数。
因为
k
n
∣
p
kn|p
kn∣p,所以
k
∣
p
n
k|\dfrac p n
k∣np.
所以
∑
k
=
1
∞
μ
(
k
)
∑
k
n
∣
p
f
(
p
)
=
∑
n
∣
p
f
(
p
)
∑
d
∣
p
n
μ
(
d
)
\sum\limits_{k=1}^\infin\mu(k)\sum\limits_{kn|p}f(p)=\sum\limits_{n|p}f(p)\sum\limits_{d|\frac p n}\mu(d)
k=1∑∞μ(k)kn∣p∑f(p)=n∣p∑f(p)d∣np∑μ(d)
对
∑
d
∣
p
n
μ
(
d
)
\sum\limits_{d|\frac p n}\mu(d)
d∣np∑μ(d)的讨论同上,最终得出
∑
n
∣
p
f
(
p
)
∑
d
∣
p
n
μ
(
d
)
=
f
(
n
)
\sum\limits_{n|p}f(p)\sum\limits_{d|\frac p n}\mu(d)=f(n)
n∣p∑f(p)d∣np∑μ(d)=f(n)
得证。
整除分块
引入
先看一个问题:求
∑
i
=
1
n
⌊
n
i
⌋
\sum\limits_{i=1}^n\lfloor\dfrac n i\rfloor
i=1∑n⌊in⌋的值,
1
≤
n
≤
1
0
12
1\le n\le 10^{12}
1≤n≤1012.
暴力显然,时间复杂度为
O
(
n
)
O(n)
O(n),无法通过这题。
关于整除分块
整除分块,又称数论分块,能够在 O ( n ) O(\sqrt n) O(n)的时间复杂度内解决引入中的问题。
其原理是不同的数做整除运算时可能有相同的结果,利用这一点合理分块,大大降低时间复杂度。
对一个整除和式分成多个块,故称整除分块。
只可用于整除式。
学习整除分块,是因为莫比乌斯反演中很多和式最后都会带有整除和式,运用整除分块就可以非常快速地求出整除和式的值。
这篇博客的整除分块写得很好,可以说是全网最详细了。
基础推导
首先观察下表。
x | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
y = ⌊ 20 x ⌋ y=\lfloor\dfrac {20} x\rfloor y=⌊x20⌋ | 20 | 10 | 6 | 5 | 4 | 3 | 2 | 2 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
显然,
y
=
⌊
n
x
⌋
y=\lfloor\dfrac n x\rfloor
y=⌊xn⌋的函数值是单调递减的,
⌊
n
x
⌋
\lfloor\dfrac n x\rfloor
⌊xn⌋相同的
x
x
x一定是连续的。
举个栗子,上表中
y
=
⌊
20
x
⌋
y=\lfloor\dfrac {20} x\rfloor
y=⌊x20⌋的值为
2
2
2的
x
x
x是
7
7
7到
10
10
10这一连续段。
对于上表,计算
∑
x
=
1
20
⌊
20
x
⌋
\sum\limits_{x=1}^{20}\lfloor\dfrac {20} x\rfloor
x=1∑20⌊x20⌋的值,除了可以暴力计算外,还可以
20
×
1
+
10
×
1
+
6
×
1
+
5
×
1
+
4
×
1
+
3
×
1
+
2
×
4
+
1
×
10
20\times 1+10\times 1+6\times 1+5\times 1+4\times 1+3\times 1+2\times 4+1\times 10
20×1+10×1+6×1+5×1+4×1+3×1+2×4+1×10.
这就是整除分块的基本思想,把
⌊
n
x
⌋
\lfloor\dfrac n x\rfloor
⌊xn⌋值相同的
x
x
x分成一块,用块长乘块值得到这个块的贡献。
那么为什么其时间复杂度为
O
(
n
)
O(\sqrt n)
O(n)呢?
我们要充分发挥数形结合的数学思想,就可以巧妙地不严谨证明了。
观察下图,这是
y
=
10
x
y=\dfrac {10} x
y=x10的函数图像,
C
C
C点为
(
10
,
10
)
(\sqrt {10},\sqrt{10})
(10,10)。
显然,这个函数图像关于直线
y
=
x
y=x
y=x对称。
那么在
C
C
C点左侧,有
n
\sqrt n
n个整数
x
x
x,那么最多有
n
\sqrt n
n个整点。
那么将函数图像沿直线
y
=
x
y=x
y=x翻折,得到
C
C
C点右侧也最多有
n
\sqrt n
n个整点。显然,
C
C
C点右侧的整点的纵坐标
y
y
y值只有
n
\sqrt n
n个取值。
所以总共最多有
2
n
2\sqrt n
2n个整点,分块后计算的时间复杂度为
O
(
n
)
O(\sqrt n)
O(n).
那么我们如何计算块长乘块值呢?
假设我们知道一个块的左端点
l
l
l,显然块值
k
=
⌊
n
l
⌋
k=\lfloor\dfrac n l\rfloor
k=⌊ln⌋.
如何求右端点
r
r
r?
可以发现,块内的值
i
i
i满足
i
k
≤
n
ik\le n
ik≤n,即
i
≤
⌊
n
k
⌋
i\le \lfloor\dfrac n k\rfloor
i≤⌊kn⌋,
r
r
r就是
i
i
i的最大值,即
r
=
⌊
n
k
⌋
r=\lfloor\dfrac n k\rfloor
r=⌊kn⌋。
因为
k
=
⌊
n
l
⌋
k=\lfloor\dfrac n l\rfloor
k=⌊ln⌋,所以
r
=
⌊
n
k
⌋
=
⌊
n
⌊
n
l
⌋
⌋
r=\lfloor\dfrac n k\rfloor=\left\lfloor{\dfrac n {\lfloor\dfrac n l\rfloor}}\right\rfloor
r=⌊kn⌋=
⌊ln⌋n
这就是最基础的整除分块。
简单扩展
求
∑
i
=
1
m
i
n
(
n
,
m
)
⌊
n
i
⌋
⌊
m
i
⌋
\sum\limits_{i=1}^{min(n,m)}\lfloor\dfrac n i\rfloor\lfloor\dfrac m i\rfloor
i=1∑min(n,m)⌊in⌋⌊im⌋
这个式子很重要,很多莫反的题目最后都包含这个式子。
其实非常简单,对于这个式子,仍然有
⌊
n
i
⌋
\lfloor\dfrac n i\rfloor
⌊in⌋和
⌊
m
i
⌋
\lfloor\dfrac m i\rfloor
⌊im⌋的值都分别相等的一段
x
x
x.
不懂的话像上面一样列表即可发现。
一个块的右端点就是对
⌊
n
i
⌋
\lfloor\dfrac n i\rfloor
⌊in⌋整除分块的右端点和对
⌊
m
i
⌋
\lfloor\dfrac m i\rfloor
⌊im⌋整除分块的右端点的较小值。
具体见代码。
for(int i = 1; i <= min(n, m);) {
int l = i, r = min(n / (n / i), m / (m / i));
ans += 1ll * (n / l) * (m / l) * (r - l + 1), i = r + 1;
}
更多关于整除分块的探讨在上文提到的文章中有写到。
莫比乌斯反演的应用
例1:证明下式成立
∑
d
∣
n
μ
(
d
)
n
d
=
ϕ
(
n
)
\sum\limits_{d|n}\mu(d)\dfrac n d=\phi(n)
d∣n∑μ(d)dn=ϕ(n)
证明:
设
F
(
n
)
=
n
,
f
(
n
)
=
ϕ
(
n
)
F(n)=n,f(n)=\phi(n)
F(n)=n,f(n)=ϕ(n)
因为
n
=
∑
d
∣
n
ϕ
(
d
)
n=\sum\limits_{d|n}\phi(d)
n=d∣n∑ϕ(d),所以
F
(
n
)
=
∑
d
∣
n
f
(
d
)
F(n)=\sum\limits_{d|n}f(d)
F(n)=d∣n∑f(d).
使用公式1反演
f
(
n
)
f(n)
f(n),得
ϕ
(
n
)
=
f
(
n
)
=
∑
d
∣
n
μ
(
d
)
F
(
n
d
)
=
∑
d
∣
n
μ
(
d
)
n
d
\phi(n)=f(n)=\sum\limits_{d|n}\mu(d)F(\dfrac n d)=\sum\limits_{d|n}\mu(d)\dfrac n d
ϕ(n)=f(n)=d∣n∑μ(d)F(dn)=d∣n∑μ(d)dn
例2:YY的GCD
题目
题目大意:给定
n
,
m
(
1
≤
n
,
m
≤
1
0
7
)
n,m(1\le n,m\le 10^7)
n,m(1≤n,m≤107),求
∑
i
=
1
n
∑
j
=
1
m
[
(
i
,
j
)
∈
P
]
\sum\limits_{i=1}^n\sum\limits_{j=1}^m[(i,j)\in P]
i=1∑nj=1∑m[(i,j)∈P],有
C
(
1
≤
T
≤
1
0
4
)
C(1\le T\le 10^4)
C(1≤T≤104)次询问。
设
f
(
p
)
f(p)
f(p)为二元组
(
x
,
y
)
(x,y)
(x,y)在各自的值域范围内满足
(
x
,
y
)
=
p
(x,y)=p
(x,y)=p的二元组数量,即
f
(
p
)
=
∑
i
=
1
n
∑
j
=
1
m
[
(
x
,
y
)
=
p
]
f(p)=\sum\limits_{i=1}^n\sum\limits_{j=1}^m[(x,y)=p]
f(p)=i=1∑nj=1∑m[(x,y)=p]
设
F
(
p
)
F(p)
F(p)为二元组
(
x
,
y
)
(x,y)
(x,y)在各自的值域范围内满足
p
∣
(
x
,
y
)
p|(x,y)
p∣(x,y)的二元组数量,即
F
(
p
)
=
∑
i
=
1
n
∑
j
=
1
m
[
p
∣
(
x
,
y
)
]
F(p)=\sum\limits_{i=1}^n\sum\limits_{j=1}^m[p|(x,y)]
F(p)=i=1∑nj=1∑m[p∣(x,y)]
设
P
P
P为区间
[
1
,
m
i
n
(
n
,
m
)
]
[1,min(n,m)]
[1,min(n,m)]内的质数集合。
有
F
(
p
)
=
∑
p
∣
d
f
(
d
)
F(p)=\sum\limits_{p|d}f(d)
F(p)=p∣d∑f(d),所以
f
(
p
)
=
∑
p
∣
d
μ
(
d
p
)
F
(
d
)
f(p)=\sum\limits_{p|d}\mu(\dfrac d p)F(d)
f(p)=p∣d∑μ(pd)F(d)
F
(
1
)
=
∑
p
≤
n
f
(
p
)
F(1)=\sum\limits_{p\le n}f(p)
F(1)=p≤n∑f(p),
f
(
1
)
=
∑
d
=
1
∞
μ
(
d
)
F
(
d
)
f(1)=\sum\limits_{d=1}^\infin\mu(d)F(d)
f(1)=d=1∑∞μ(d)F(d)
答案就是
∑
p
∈
P
,
x
≤
n
,
y
≤
m
f
(
p
)
\sum\limits_{p\in P,x\le n,y\le m}f(p)
p∈P,x≤n,y≤m∑f(p)
因为
(
x
,
y
)
=
p
(x,y)=p
(x,y)=p,所以计算
x
≤
⌊
n
p
⌋
,
y
≤
⌊
m
p
⌋
x\le \lfloor\dfrac n p \rfloor,y\le \lfloor \dfrac m p \rfloor
x≤⌊pn⌋,y≤⌊pm⌋范围内
(
x
,
y
)
=
1
(x,y)=1
(x,y)=1的值与原式的值等价。
∑
p
∈
P
,
x
≤
n
,
y
≤
m
f
(
p
)
=
∑
p
∈
P
,
x
≤
n
p
,
y
≤
m
p
f
(
1
)
=
∑
p
∈
P
,
x
≤
n
p
,
y
≤
m
p
,
1
∣
d
F
(
d
)
μ
(
d
)
\sum\limits_{p\in P,x\le n,y\le m}f(p)\\=\sum\limits_{p\in P,x\le \frac n p,y\le \frac m p}f(1)\\=\sum\limits_{p\in P,x\le \frac n p,y\le \frac m p,1|d}F(d)\mu(d)
p∈P,x≤n,y≤m∑f(p)=p∈P,x≤pn,y≤pm∑f(1)=p∈P,x≤pn,y≤pm,1∣d∑F(d)μ(d)
推导
F
(
p
)
=
∑
i
=
1
n
∑
j
=
1
m
[
p
∣
(
x
,
y
)
]
=
∑
i
=
1
⌊
n
p
⌋
∑
j
=
1
⌊
m
p
⌋
[
1
∣
(
x
,
y
)
]
=
⌊
n
p
⌋
×
⌊
m
p
⌋
F(p)=\sum\limits_{i=1}^n\sum\limits_{j=1}^m[p|(x,y)]=\sum\limits_{i=1}^{\lfloor\frac n p\rfloor}\sum\limits_{j=1}^{\lfloor\frac m p\rfloor}[1|(x,y)]=\lfloor\frac n p\rfloor\times \lfloor\frac m p\rfloor
F(p)=i=1∑nj=1∑m[p∣(x,y)]=i=1∑⌊pn⌋j=1∑⌊pm⌋[1∣(x,y)]=⌊pn⌋×⌊pm⌋,注意这里的
x
,
y
x,y
x,y取值分别是
n
,
m
n,m
n,m之内。
所以
∑
p
∈
P
,
x
≤
n
p
,
y
≤
m
p
,
1
∣
d
F
(
d
)
μ
(
d
)
=
∑
p
∈
P
,
x
≤
n
p
,
y
≤
m
p
,
1
∣
d
μ
(
d
)
⌊
n
p
d
⌋
×
⌊
m
p
d
⌋
\sum\limits_{p\in P,x\le \frac n p,y\le \frac m p,1|d}F(d)\mu(d)=\sum\limits_{p\in P,x\le \frac n p,y\le \frac m p,1|d}\mu(d)\lfloor\dfrac n {pd}\rfloor\times \lfloor\dfrac m {pd}\rfloor
p∈P,x≤pn,y≤pm,1∣d∑F(d)μ(d)=p∈P,x≤pn,y≤pm,1∣d∑μ(d)⌊pdn⌋×⌊pdm⌋
这里
n
n
n要多除以一个
p
p
p的原因是
F
(
d
)
F(d)
F(d)中的二元组
(
x
,
y
)
(x,y)
(x,y)的范围是
⌊
n
p
⌋
,
⌊
m
p
⌋
\lfloor\frac n p\rfloor,\lfloor\frac m p\rfloor
⌊pn⌋,⌊pm⌋.
令
T
=
p
d
T=pd
T=pd,则
∑
p
∈
P
,
x
≤
n
p
,
y
≤
m
p
,
1
∣
d
μ
(
d
)
⌊
n
p
d
⌋
×
⌊
m
p
d
⌋
=
∑
p
∈
P
,
T
≤
m
i
n
(
n
,
m
)
μ
(
T
p
)
⌊
n
T
⌋
⌊
m
T
⌋
\sum\limits_{p\in P,x\le \frac n p,y\le \frac m p,1|d}\mu(d)\lfloor\dfrac n {pd}\rfloor\times \lfloor\dfrac m {pd}\rfloor=\sum\limits_{p\in P,T\le min(n,m)}\mu(\dfrac T p)\lfloor\dfrac n T\rfloor\lfloor\dfrac m T\rfloor
p∈P,x≤pn,y≤pm,1∣d∑μ(d)⌊pdn⌋×⌊pdm⌋=p∈P,T≤min(n,m)∑μ(pT)⌊Tn⌋⌊Tm⌋
考虑对于
⌊
n
T
⌋
⌊
m
T
⌋
\lfloor\dfrac n T\rfloor\lfloor\dfrac m T\rfloor
⌊Tn⌋⌊Tm⌋求其系数,容易发现系数为
∑
p
∣
T
μ
(
T
p
)
\sum\limits_{p|T}\mu(\dfrac T p)
p∣T∑μ(pT)
则
∑
p
∈
P
,
T
≤
m
i
n
(
n
,
m
)
μ
(
T
p
)
⌊
n
T
⌋
⌊
m
T
⌋
=
∑
T
≤
m
i
n
(
n
,
m
)
⌊
n
T
⌋
⌊
m
T
⌋
∑
p
∣
T
μ
(
T
p
)
\sum\limits_{p\in P,T\le min(n,m)}\mu(\dfrac T p)\lfloor\dfrac n T\rfloor\lfloor\dfrac m T\rfloor=\sum\limits_{T\le min(n,m)}\lfloor\dfrac n T\rfloor\lfloor\dfrac m T\rfloor\sum\limits_{p|T}\mu(\dfrac T p)
p∈P,T≤min(n,m)∑μ(pT)⌊Tn⌋⌊Tm⌋=T≤min(n,m)∑⌊Tn⌋⌊Tm⌋p∣T∑μ(pT)
对于
⌊
n
T
⌋
⌊
m
T
⌋
\lfloor\dfrac n T\rfloor\lfloor\dfrac m T\rfloor
⌊Tn⌋⌊Tm⌋,可以用整除分块,对于后面的
∑
p
∣
T
μ
(
T
p
)
\sum\limits_{p|T}\mu(\dfrac T p)
p∣T∑μ(pT)可以预处理出前缀和来计算。
首先线性筛出所有
μ
\mu
μ函数的值,然后枚举质数
p
p
p,再枚举其倍数
T
p
\dfrac T p
pT,将
μ
(
T
p
)
\mu(\dfrac T p)
μ(pT)的值累加到
s
u
m
[
T
]
sum[T]
sum[T]中。
这样计算看起来很慢,但其实是很快的。
这样计算的时间复杂度为
∑
p
∣
T
(
T
p
)
=
T
∑
p
∣
T
1
p
<
T
∑
x
=
1
T
1
x
<
T
ln
T
\sum\limits_{p|T}(\dfrac T p)=T\sum\limits_{p|T}\dfrac 1 p<T\sum\limits_{x=1}^T\dfrac 1 x<T\ln T
p∣T∑(pT)=Tp∣T∑p1<Tx=1∑Tx1<TlnT
所以每个质数均摊的时间复杂度为
O
(
ln
T
)
O(\ln T)
O(lnT),而质数个数有
T
ln
T
\dfrac T {\ln T}
lnTT个,所以预处理的时间复杂度为
O
(
T
)
O(T)
O(T)
通过整除分块,每组数据可以在
O
(
n
)
O(\sqrt n)
O(n)的时间复杂度内计算,所以总的时间复杂度为
O
(
C
n
)
O(C\sqrt n)
O(Cn)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 10000005;
int T, n, m, mu[N], smu[N], vis[N], pri[N], cnt = 0;
void getmu() {
mu[1] = 1;
for (int i = 2; i < N; i++) {
if (!vis[i]) pri[++cnt] = i, mu[i] = -1;
for (int j = 1; j <= cnt && i * pri[j] < N; j++) {
vis[i * pri[j]] = 1;
if (i % pri[j] == 0) break;
mu[i * pri[j]] = -mu[i];
}
}
}
void getsmu() {
for (int i = 1; i <= cnt; i++)
for (int j = 1; pri[i] * j < N; j++)
smu[pri[i] * j] += mu[j];
for (int i = 2; i < N; i++) smu[i] += smu[i - 1];
}
int main() {
scanf("%d", &T);
getmu(), getsmu();
while (T--) {
scanf("%d%d", &n, &m);
LL ans = 0;
for (int i = 1; i <= min(n, m);) {
int l = i, r = min(n / (n / i), m / (m / i));
ans += 1ll * (smu[r] - smu[l - 1]) * (n / l) * (m / l), i = r + 1;
}
printf("%lld\n", ans);
}
return 0;
}
例3:Problem b
题目
题目大意:对于给定的
a
,
b
,
c
,
d
,
k
a,b,c,d,k
a,b,c,d,k,求
∑
x
=
a
b
∑
y
=
c
d
[
(
x
,
y
)
=
k
]
\sum\limits_{x=a}^b\sum\limits_{y=c}^d[(x,y)=k]
x=a∑by=c∑d[(x,y)=k]. 有
N
N
N次询问。
设
f
n
,
m
(
k
)
=
∑
x
=
1
n
∑
y
=
1
m
[
(
x
,
y
)
=
k
]
F
n
,
m
(
k
)
=
∑
x
=
1
n
∑
y
=
1
m
[
k
∣
(
x
,
y
)
]
f_{n,m}(k)=\sum\limits_{x=1}^n\sum\limits_{y=1}^m[(x,y)=k]\\F_{n,m}(k)=\sum\limits_{x=1}^n\sum\limits_{y=1}^m[k|(x,y)]
fn,m(k)=x=1∑ny=1∑m[(x,y)=k]Fn,m(k)=x=1∑ny=1∑m[k∣(x,y)]
有
F
A
,
B
(
k
)
=
∑
k
∣
n
f
A
,
B
(
n
)
F_{A,B}(k)=\sum\limits_{k|n}f_{A,B}(n)
FA,B(k)=k∣n∑fA,B(n)
则答案为
f
b
,
d
(
k
)
−
f
a
−
1
,
d
(
k
)
−
f
b
,
c
−
1
(
k
)
+
f
a
−
1
,
c
−
1
(
k
)
f_{b,d}(k)-f_{a-1,d}(k)-f_{b,c-1}(k)+f_{a-1,c-1}(k)
fb,d(k)−fa−1,d(k)−fb,c−1(k)+fa−1,c−1(k),类似于二维前缀和的容斥。
F n , m ( k ) F_{n,m}(k) Fn,m(k)是很好求的,它等于 ⌊ n k ⌋ ⌊ m k ⌋ \lfloor \dfrac n k\rfloor\lfloor \dfrac m k\rfloor ⌊kn⌋⌊km⌋.
这是因为在 n n n内有 ⌊ n k ⌋ \lfloor \dfrac n k\rfloor ⌊kn⌋个数包含因子 k k k,同理,在 m m m内有 ⌊ m k ⌋ \lfloor \dfrac m k\rfloor ⌊km⌋个数包含因子 k k k.
根据乘法原理,有 ⌊ n k ⌋ ⌊ m k ⌋ \lfloor \dfrac n k\rfloor\lfloor \dfrac m k\rfloor ⌊kn⌋⌊km⌋对二元组 ( x , y ) (x,y) (x,y)满足 k ∣ g c d ( x , y ) k|gcd(x,y) k∣gcd(x,y).
运用莫反,有
f
(
n
)
A
,
B
=
∑
n
∣
k
μ
(
k
n
)
F
A
,
B
(
k
)
=
∑
n
∣
k
μ
(
k
n
)
⌊
A
k
⌋
⌊
B
k
⌋
f(n)_{A,B}=\sum\limits_{n|k}\mu(\dfrac k n)F_{A,B}(k)=\sum\limits_{n|k}\mu(\dfrac k n)\lfloor \dfrac A k\rfloor\lfloor \dfrac B k\rfloor
f(n)A,B=n∣k∑μ(nk)FA,B(k)=n∣k∑μ(nk)⌊kA⌋⌊kB⌋
令
T
=
k
n
T=\dfrac k n
T=nk,有
f
(
n
)
A
,
B
=
∑
n
∣
k
μ
(
k
n
)
⌊
A
k
⌋
⌊
B
k
⌋
=
∑
T
=
1
m
i
n
(
A
,
B
)
μ
(
T
)
⌊
A
T
n
⌋
⌊
B
T
n
⌋
f(n)_{A,B}=\sum\limits_{n|k}\mu(\dfrac k n)\lfloor \dfrac A k\rfloor\lfloor \dfrac B k\rfloor=\sum\limits_{T=1}^{min(A,B)}\mu(T)\lfloor \dfrac A {Tn}\rfloor\lfloor \dfrac B {Tn}\rfloor
f(n)A,B=n∣k∑μ(nk)⌊kA⌋⌊kB⌋=T=1∑min(A,B)μ(T)⌊TnA⌋⌊TnB⌋
运用整除分块+预处理,时间复杂度可以做到 O ( N n ) O(N\sqrt n) O(Nn), n n n最大为 5 × 1 0 4 5\times 10^4 5×104.
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 50005;
int T, a, b, c, d, k, vis[N], pri[N], cnt = 0, mu[N], sum[N];
void getmu() {
mu[1] = 1;
for (int i = 2; i < N; i++) {
if (!vis[i]) pri[++cnt] = i, mu[i] = -1;
for (int j = 1; j <= cnt && i * pri[j] < N; j++) {
vis[i * pri[j]] = 1;
if (i % pri[j] == 0) break;
mu[i * pri[j]] = -mu[i];
}
}
for (int i = 1; i < N; i++) sum[i] = sum[i - 1] + mu[i];
}
LL getans(int x, int y) {
LL s = 0;
for (int i = 1; i <= min(x, y);) {
LL l = i, r = min(x / (x / i), y / (y / i));
s += 1ll * (sum[r] - sum[l - 1]) * (x / (l * k)) * (y / (l * k)), i = r + 1;
}
return s;
}
int main() {
scanf("%d", &T);
getmu();
while (T--) scanf("%d%d%d%d%d", &a, &b, &c, &d, &k), printf("%lld\n", getans(b, d) - getans(b, c - 1) - getans(a - 1, d) + getans(a - 1, c - 1));
return 0;
}
例4:完全平方数
题目
题目大意:正整数集合中,若一个数是平方数(
1
1
1 除外)的正整数倍,称这个数为坏的数,否则为好的数。求第
K
(
1
≤
K
≤
1
0
9
)
K(1\le K\le 10^9)
K(1≤K≤109)个好的数。有
T
(
1
≤
T
≤
50
)
T(1\le T\le 50)
T(1≤T≤50)次询问。
这题实际上是莫比乌斯函数的巧妙运用。
如果我们知道
[
1
,
n
]
[1,n]
[1,n]内有多少个好的数,就可以用二分解决。
考虑如何求
[
1
,
n
]
[1,n]
[1,n]内有多少个好的数。
好的数不好直接求,转化为
n
n
n减去坏的数的数量。
在区间
[
1
,
n
]
[1,n]
[1,n]内有
⌊
n
4
⌋
\lfloor\dfrac n 4\rfloor
⌊4n⌋个数为
2
2
=
4
2^2=4
22=4的倍数,那当然不需要计算
⌊
n
16
⌋
\lfloor\dfrac n {16}\rfloor
⌊16n⌋的倍数。
所以只需要计算质数的倍数即可。
从而想到容斥。
从总数
n
n
n中删去
4
4
4的倍数,再删去
9
9
9的倍数时,显然
36
36
36的倍数被多删掉了,要加回来。
那么容斥的边界是什么呢?
对于质数
p
p
p,显然其平方的倍数有
⌊
n
p
2
⌋
\lfloor\dfrac n {p^2}\rfloor
⌊p2n⌋个。那么当
p
p
p大于
⌊
n
⌋
\lfloor\sqrt n\rfloor
⌊n⌋时,
⌊
n
p
2
⌋
=
0
\lfloor\dfrac n {p^2}\rfloor=0
⌊p2n⌋=0. 所以容斥的边界为
p
≤
⌊
n
⌋
p\le \lfloor\sqrt n\rfloor
p≤⌊n⌋.
前置知识中提到,莫比乌斯函数具有很好的容斥天赋,这题就是很好的体现。
当我们rp=max就可以想到坏的数的个数等于
∑
p
∈
P
n
μ
(
p
)
⌊
n
p
2
⌋
\sum\limits_{p\in P}^{\sqrt n}\mu(p)\lfloor\dfrac n {p^2}\rfloor
p∈P∑nμ(p)⌊p2n⌋.
至此思路显然。
如果没有AC就把二分和
n
n
n的上限往死里开。
时间复杂度为 O ( T r m a x log K ) O(T\sqrt {r_{max}}\log K) O(TrmaxlogK),其中 r m a x r_{max} rmax表示二分的上限。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 50005;
int T, k, mu[N], pri[N], cnt = 0, vis[N];
void getmu() {
mu[1] = 1;
for (int i = 2; i < N; i++) {
if (!vis[i]) pri[++cnt] = i, mu[i] = -1;
for (int j = 1; j <= cnt && i * pri[j] < N; j++) {
vis[i * pri[j]] = 1;
if (i % pri[j] == 0) break;
mu[i * pri[j]] = -mu[i];
}
}
}
bool check(LL x) {
LL sum = 0;
for (LL i = 1; i <= sqrt(x); i++) sum += mu[i] * (x / (i * i));
if (sum >= k) return false;
return true;
}
int main() {
scanf("%d", &T);
getmu();
while (T--) {
scanf("%d", &k);
LL ans = 0, l = 0, r = 2e9;
while (l <= r) {
LL mid = l + r >> 1;
if (check(mid) == true) l = mid + 1;
else r = mid - 1, ans = mid;
}
printf("%d\n", ans);
}
return 0;
}
例5:约数个数和
题目
题目大意:设
d
(
n
)
d(n)
d(n)为
n
n
n的约数个数,给定
n
,
m
(
1
≤
n
,
m
≤
50000
)
n,m(1\le n,m\le 50000)
n,m(1≤n,m≤50000),求
∑
i
=
1
n
∑
j
=
1
m
d
(
i
j
)
\sum\limits_{i=1}^n\sum\limits_{j=1}^md(ij)
i=1∑nj=1∑md(ij). 有
T
T
T组询问。
设
f
(
k
)
=
∑
i
=
1
n
∑
j
=
1
m
[
(
i
,
j
)
=
k
]
F
(
k
)
=
∑
i
=
1
n
∑
j
=
1
m
[
k
∣
(
i
,
j
)
]
=
∑
k
∣
d
f
(
d
)
f(k)=\sum\limits_{i=1}^n\sum\limits_{j=1}^m[(i,j)=k]\\F(k)=\sum\limits_{i=1}^n\sum\limits_{j=1}^m[k|(i,j)]=\sum\limits_{k|d}f(d)
f(k)=i=1∑nj=1∑m[(i,j)=k]F(k)=i=1∑nj=1∑m[k∣(i,j)]=k∣d∑f(d)
关于约数个数,有如下公式:
d
(
i
j
)
=
∑
x
∣
i
∑
y
∣
j
[
(
x
,
y
)
=
1
]
d(ij)=\sum\limits_{x|i}\sum\limits_{y|j}[(x,y)=1]
d(ij)=x∣i∑y∣j∑[(x,y)=1]
证明不会。手玩或许可以感性理解。
所以有
a
n
s
=
∑
i
=
1
n
∑
j
=
1
m
∑
x
∣
i
∑
y
∣
j
[
(
x
,
y
)
=
1
]
ans=\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x|i}\sum\limits_{y|j}[(x,y)=1]
ans=i=1∑nj=1∑mx∣i∑y∣j∑[(x,y)=1]
因为
∑
d
∣
n
=
μ
(
d
)
=
[
n
=
1
]
\sum\limits_{d|n}=\mu(d)=[n=1]
d∣n∑=μ(d)=[n=1],所以
a
n
s
=
∑
i
=
1
n
∑
j
=
1
m
∑
x
∣
i
∑
y
∣
j
∑
d
∣
(
i
,
j
)
μ
(
d
)
=
∑
i
=
1
n
∑
j
=
1
m
∑
x
∣
i
∑
y
∣
j
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
×
[
d
∣
(
x
,
y
)
]
ans=\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x|i}\sum\limits_{y|j}\sum\limits_{d|(i,j)}\mu(d)\\=\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x|i}\sum\limits_{y|j}\sum\limits_{d=1}^{min(n,m)}\mu(d)\times[d|(x,y)]
ans=i=1∑nj=1∑mx∣i∑y∣j∑d∣(i,j)∑μ(d)=i=1∑nj=1∑mx∣i∑y∣j∑d=1∑min(n,m)μ(d)×[d∣(x,y)]
能够变换的原因是只有当
d
∣
(
x
,
y
)
d|(x,y)
d∣(x,y)时才对
μ
(
d
)
\mu(d)
μ(d)有贡献。
对于每个
μ
(
d
)
\mu(d)
μ(d),对其作出的贡献,即它的系数,为
∑
i
=
1
n
∑
j
=
1
m
∑
x
∣
i
∑
y
∣
j
[
d
∣
(
x
,
y
)
]
\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x|i}\sum\limits_{y|j}[d|(x,y)]
i=1∑nj=1∑mx∣i∑y∣j∑[d∣(x,y)].
所以有
a
n
s
=
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
∑
i
=
1
n
∑
j
=
1
m
∑
x
∣
i
∑
y
∣
j
[
d
∣
(
x
,
y
)
]
ans=\sum\limits_{d=1}^{min(n,m)}\mu(d)\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x|i}\sum\limits_{y|j}[d|(x,y)]
ans=d=1∑min(n,m)μ(d)i=1∑nj=1∑mx∣i∑y∣j∑[d∣(x,y)]
考虑直接枚举
x
,
y
x,y
x,y,若有
d
∣
(
x
,
y
)
d|(x,y)
d∣(x,y),则有
i
i
i的取值有
⌊
n
x
⌋
\lfloor\dfrac n x\rfloor
⌊xn⌋个,
j
j
j的取值有
⌊
m
y
⌋
\lfloor\dfrac m y\rfloor
⌊ym⌋个。
所以有
a
n
s
=
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
∑
x
=
1
n
∑
y
=
1
m
[
d
∣
(
x
,
y
)
]
⌊
n
x
⌋
⌊
m
y
⌋
ans=\sum\limits_{d=1}^{min(n,m)}\mu(d)\sum\limits_{x=1}^n\sum\limits_{y=1}^m[d|(x,y)]\lfloor\dfrac n x\rfloor\lfloor\dfrac m y\rfloor
ans=d=1∑min(n,m)μ(d)x=1∑ny=1∑m[d∣(x,y)]⌊xn⌋⌊ym⌋
更换枚举项,设
x
′
=
d
x
,
y
′
=
d
y
x'=dx,y'=dy
x′=dx,y′=dy,则
a
n
s
=
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
∑
x
′
=
1
⌊
n
d
⌋
∑
y
′
=
1
⌊
m
d
⌋
[
d
∣
(
x
′
,
y
′
)
]
⌊
n
d
x
′
⌋
⌊
m
d
y
′
⌋
=
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
∑
x
′
=
1
⌊
n
d
⌋
∑
y
′
=
1
⌊
m
d
⌋
⌊
n
d
x
′
⌋
⌊
m
d
y
′
⌋
ans=\sum\limits_{d=1}^{min(n,m)}\mu(d)\sum\limits_{x'=1}^{\lfloor\frac n d\rfloor}\sum\limits_{y'=1}^{\lfloor\frac m d\rfloor}[d|(x',y')]\lfloor\dfrac n {dx'}\rfloor\lfloor\dfrac m {dy'}\rfloor\\=\sum\limits_{d=1}^{min(n,m)}\mu(d)\sum\limits_{x'=1}^{\lfloor\frac n d\rfloor}\sum\limits_{y'=1}^{\lfloor\frac m d\rfloor}\lfloor\dfrac n {dx'}\rfloor\lfloor\dfrac m {dy'}\rfloor
ans=d=1∑min(n,m)μ(d)x′=1∑⌊dn⌋y′=1∑⌊dm⌋[d∣(x′,y′)]⌊dx′n⌋⌊dy′m⌋=d=1∑min(n,m)μ(d)x′=1∑⌊dn⌋y′=1∑⌊dm⌋⌊dx′n⌋⌊dy′m⌋
类比
∑
i
=
1
a
∑
j
=
1
b
i
j
=
(
∑
i
=
1
a
i
)
(
∑
j
=
1
b
j
)
\sum\limits_{i=1}^a\sum\limits_{j=1}^bij=(\sum\limits_{i=1}^a i)(\sum\limits_{j=1}^b j)
i=1∑aj=1∑bij=(i=1∑ai)(j=1∑bj),有
a
n
s
=
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
(
∑
x
′
=
1
⌊
n
d
⌋
⌊
n
d
x
′
⌋
)
(
∑
y
′
=
1
⌊
m
d
⌋
⌊
m
d
y
′
⌋
)
ans=\sum\limits_{d=1}^{min(n,m)}\mu(d)(\sum\limits_{x'=1}^{\lfloor\frac n d\rfloor}\lfloor\dfrac n {dx'}\rfloor)(\sum\limits_{y'=1}^{\lfloor\frac m d\rfloor}\lfloor\dfrac m {dy'}\rfloor)
ans=d=1∑min(n,m)μ(d)(x′=1∑⌊dn⌋⌊dx′n⌋)(y′=1∑⌊dm⌋⌊dy′m⌋)
将
∑
i
=
1
n
⌊
n
i
⌋
\sum\limits_{i=1}^n\lfloor\dfrac n i\rfloor
i=1∑n⌊in⌋花费
O
(
n
n
)
O(n\sqrt n)
O(nn)的时间整除分块预处理得到
s
u
m
[
i
]
sum[i]
sum[i],则
a
n
s
=
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
s
u
m
[
n
d
]
s
u
m
[
m
d
]
ans=\sum\limits_{d=1}^{min(n,m)}\mu(d)sum[\dfrac n d]sum[\dfrac m d]
ans=d=1∑min(n,m)μ(d)sum[dn]sum[dm]
此时再对
n
d
,
m
d
\dfrac n d,\dfrac m d
dn,dm整除分块,每次询问的时间复杂度为
O
(
n
)
O(\sqrt n)
O(n). 加上
T
T
T组询问,总的时间复杂度为
O
(
T
n
)
O(T\sqrt n)
O(Tn).
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 50005;
int T, n, m, mu[N], vis[N], pri[N], cnt = 0;
LL f[N];
void getf() {
for (int i = 1; i < N; i++)
for (int l = 1, r; l <= i; l = r + 1) {
r = i / (i / l);
f[i] += 1ll * (r - l + 1) * (i / l);
}
}
void getmu() {
mu[1] = 1;
for (int i = 2; i < N; i++) {
if (!vis[i]) pri[++cnt] = i, mu[i] = -1;
for (int j = 1; j <= cnt && i * pri[j] < N; j++) {
vis[i * pri[j]] = 1;
if (i % pri[j] == 0) break;
mu[i * pri[j]] = -mu[i];
}
}
for (int i = 2; i < N; i++) mu[i] += mu[i - 1];
}
int main() {
getf(), getmu();
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
LL ans = 0;
for (int i = 1, r; i <= min(n, m); i = r + 1) {
r = min(n / (n / i), m / (m / i));
ans += 1ll * (mu[r] - mu[i - 1]) * f[n / i] * f[m / i];
}
printf("%lld\n", ans);
}
return 0;
}
总结
莫比乌斯反演能够将难以直接求解的函数转化为容易求解的函数求值。
莫比乌斯反演的题目大都有一个或多个和式,以及 g c d gcd gcd,或者与 g c d gcd gcd紧密相关的函数,如约数和函数 σ \sigma σ.
莫比乌斯反演通常有如下步骤:
- 将原问题转化为类 ∑ i = 1 n \sum\limits_{i=1}^n i=1∑n的和式
- 设应求函数 f ( n ) f(n) f(n)和易求函数 F ( n ) F(n) F(n), F ( n ) F(n) F(n)多与 g c d gcd gcd有关,得到 F ( n ) F(n) F(n)与 f ( n ) f(n) f(n)的关系式和 F ( n ) F(n) F(n)的易求形式
- 反演 f ( n ) f(n) f(n),得到和式,带入 F ( n ) F(n) F(n)易求形式
- 和式除以 g c d gcd gcd,消除 g c d gcd gcd的影响
- 更换枚举顺序,分离 ∑ \sum ∑
- 更换枚举变量,将 ∑ \sum ∑的枚举变量变成连续的正整数,方法通常是设 d ′ = n d d'=\dfrac n d d′=dn或 d n \dfrac d n nd
- 考虑整除分块及预处理,可能有杜教筛
第 3 3 3到 6 6 6步因人而异,可能有些没有,有些顺序不同。有时候一些步骤需要重复多次。
总的来说,莫比乌斯反演的题目就是和式的变换,AC这些题目的前提就是精通和式变换。
莫比乌斯反演要多练题才能对其有比较深入的理解。
狄利克雷卷积
定义
若有数论函数 f , g , h f,g,h f,g,h,满足 h ( n ) = ∑ d ∣ n f ( d ) g ( n d ) h(n)=\sum\limits_{d|n}f(d)g(\dfrac{n}{d}) h(n)=d∣n∑f(d)g(dn),则称 h h h 是 f , g f,g f,g 的狄利克雷卷积,记为 h = f ∗ g h=f*g h=f∗g,一般读作“ f f f 卷 g g g”.
性质
1、交换律:
f ∗ g = ∑ d ∣ n f ( d ) g ( n d ) = ∑ d ∣ n f ( n d ) g ( d ) = g ∗ h f*g=\sum\limits_{d|n}f(d)g(\dfrac{n}{d})=\sum\limits_{d|n}f(\dfrac{n}{d})g(d)=g*h f∗g=d∣n∑f(d)g(dn)=d∣n∑f(dn)g(d)=g∗h
2、结合律:
设 F = f ∗ g , G = g ∗ h F=f*g,G=g*h F=f∗g,G=g∗h.
( f ∗ g ) ∗ h = ∑ d ∣ n F ( d ) h ( n d ) = ∑ d ∣ n ( ∑ k ∣ d f ( k ) g ( d k ) ) h ( n d ) (f*g)*h=\sum\limits_{d|n}F(d)h(\dfrac n d)\\=\sum\limits_{d|n}(\sum\limits_{k|d}f(k)g(\dfrac{d}{k}))h(\dfrac n d) (f∗g)∗h=d∣n∑F(d)h(dn)=d∣n∑(k∣d∑f(k)g(kd))h(dn)
考虑提出 f f f,因为 k ∣ d ∣ n k|d|n k∣d∣n,有 d ∣ n k d|\dfrac{n}{k} d∣kn.
∑ d ∣ n ( ∑ k ∣ d f ( k ) g ( d k ) ) h ( n d ) = ∑ k ∣ n f ( k ) ∑ d ∣ n k g ( d ) h ( n k d ) = ∑ k ∣ n f ( k ) G ( n k ) = f ∗ ( g ∗ h ) \sum\limits_{d|n}(\sum\limits_{k|d}f(k)g(\dfrac{d}{k}))h(\dfrac n d)=\sum\limits_{k|n}f(k)\sum\limits_{d|\frac{n}{k}}g(d)h(\dfrac{n}{kd})=\sum\limits_{k|n}f(k)G(\dfrac{n}{k})=f*(g*h) d∣n∑(k∣d∑f(k)g(kd))h(dn)=k∣n∑f(k)d∣kn∑g(d)h(kdn)=k∣n∑f(k)G(kn)=f∗(g∗h)
单位元
单位元 ϵ ( n ) = [ n = 1 ] \epsilon(n)=[n=1] ϵ(n)=[n=1],容易证明任何数卷 ϵ \epsilon ϵ 都等于本身,其地位等同于乘法运算中的 1 1 1,加法运算中的 0 0 0.
常见狄利克雷卷积
μ ∗ I = I d \mu*I=Id μ∗I=Id
μ ∗ I d = ϕ \mu*Id=\phi μ∗Id=ϕ
μ ∗ σ = I d \mu*\sigma=Id μ∗σ=Id
I d ∗ I = σ Id*I=\sigma Id∗I=σ
ϕ ∗ I = I d \phi*I=Id ϕ∗I=Id
莫比乌斯反演与狄利克雷卷积有很密切的联系。
举个栗子:
I ( n ) = ∑ d ∣ n ϵ ( d ) = 1 I(n)=\sum\limits_{d|n}\epsilon(d)=1 I(n)=d∣n∑ϵ(d)=1
依据莫比乌斯反演有 ϵ ( n ) = ∑ d ∣ n μ ( d ) I ( n d ) = μ ∗ I \epsilon(n)=\sum\limits_{d|n}\mu(d)I(\dfrac{n}{d})=\mu*I ϵ(n)=d∣n∑μ(d)I(dn)=μ∗I
狄利克雷卷积能够帮助我们更好地理解莫比乌斯反演。
总结
狄利克雷卷积实质上是一种和式的表示方式,非常简洁地表述了一串和式。
利用狄利克雷卷积可以和莫比乌斯反演互相推导,有利于我们理解莫反。