1.杜教筛
杜教筛是用来在低于线性的时间复杂度 ( O ( n 2 3 ) ? ) (O(n^\frac{2}{3} )?) (O(n32)?)内求出积性函数的前缀和的算法
根据杜教筛的定义,我们设
S
(
n
)
=
∑
i
=
1
n
f
(
i
)
S(n)=\sum_{i=1}^nf(i)
S(n)=i=1∑nf(i)
g
是
一
个
积
性
函
数
g是一个积性函数
g是一个积性函数
h
(
n
)
=
f
×
g
h(n)=f \times g
h(n)=f×g
H
(
n
)
=
∑
i
=
1
n
h
(
i
)
H(n)=\sum_{i=1}^nh(i)
H(n)=i=1∑nh(i)
那么有
H
(
n
)
=
∑
i
=
1
n
h
(
i
)
=
∑
i
=
1
n
(
f
×
g
)
(
i
)
=
∑
i
=
1
n
∑
d
∣
i
g
(
d
)
f
(
i
d
)
=
∑
i
=
1
n
∑
d
∣
i
g
(
d
)
f
(
i
d
)
=
∑
d
=
1
n
g
(
d
)
∑
i
=
1
n
f
(
i
d
)
[
d
∣
i
]
=
∑
d
=
1
n
g
(
d
)
∑
i
=
1
⌊
i
d
⌋
f
(
i
)
=
∑
d
=
1
n
g
(
d
)
S
(
⌊
i
d
⌋
)
\begin{aligned} H(n)&=\sum_{i=1}^nh(i)\\ &=\sum_{i=1}^n(f\times g)(i)\\ &=\sum_{i=1}^n\sum_{d|i}{g(d)f(\frac{i}{d})}\\ &=\sum_{i=1}^n\sum_{d|i}{g(d)f(\frac{i}{d})}\\ &=\sum_{d=1}^ng(d)\sum_{i=1}^nf(\frac{i}{d})[d|i] \\ &=\sum_{d=1}^ng(d)\sum_{i=1}^{\lfloor\frac{i}{d}\rfloor}f(i) \\ &=\sum_{d=1}^ng(d)S(\lfloor\frac{i}{d}\rfloor)\\ \end{aligned}
H(n)=i=1∑nh(i)=i=1∑n(f×g)(i)=i=1∑nd∣i∑g(d)f(di)=i=1∑nd∣i∑g(d)f(di)=d=1∑ng(d)i=1∑nf(di)[d∣i]=d=1∑ng(d)i=1∑⌊di⌋f(i)=d=1∑ng(d)S(⌊di⌋)
变化一下可得:
g
(
1
)
S
(
n
)
=
H
(
n
)
−
∑
d
=
2
n
g
(
d
)
S
(
⌊
i
d
⌋
)
\begin{aligned} g(1)S(n)&=H(n)-\sum_{d=2}^ng(d)S(\lfloor\frac{i}{d}\rfloor) \end{aligned}
g(1)S(n)=H(n)−d=2∑ng(d)S(⌊di⌋)
这就是杜教筛最根本的式子。
如果我们能找到一个g,使得g的前缀和
g
×
h
g\times h
g×h的前缀和都很好求,那我们就能用整数分块快速求出S了
应用
∑ i = 1 n μ ( i ) \sum_{i=1}^n\mu(i) i=1∑nμ(i)
我们知道
μ
×
I
=
ϵ
\mu \times I =\epsilon
μ×I=ϵ
ϵ \epsilon ϵ的前缀和永远是1, I I I的前缀和就是n
那我们就可以推出 μ \mu μ的前缀和式子了