一、引入
通常,在莫比乌斯反演的题目中会推出下面这样的式子:
∑i=1n⌊ni⌋f(i)
其中
f
是积性函数。
我们知道,当
1≤i≤n
时
⌊ni⌋
的取值只有
O(n−−√)
种。
于是我们可以对下界分块,利用
f
的前缀和求解,从而实现一次
O(n−−√)
的复杂度。
但如果
n=109
时,如何求
f
的前缀和呢?
下面就来介绍
求积性函数前缀和的算法:杜教筛。
二、前置芝士:狄利克雷 (Dirichlet) 卷积
两个数论函数函数
f
和
g
的狄利克雷卷积定义为:
(f∗g)(n)∑d|nf(d)g(nd)
如果
f
和
g
为积性函数,那么
f∗g
也是积性函数。
三、算法流程
设我们要求的值:
S(n)=∑i=1nf(i)
首先找到一个积性函数
g
,使得
h(n)=∑i=1n(f∗g)(i)
可以被
O(1)
计算出,
g(n)
的
值及前缀和也能被
O(1)
计算出。
于是有:
∑i=1n∑d|if(id)g(d)=h(n)
把枚举约数改成枚举倍数:
∑d=1ng(d)∑1≤i≤n,d|if(id)=h(n)
满足所有
1≤i≤n,d|i
的
id
实际上就是所有满足
1≤i≤⌊nd⌋
的
i
:
∑i=1ng(i)∑j=1⌊ni⌋f(j)=h(n)
于是:
∑i=1ng(i)S(⌊ni⌋)=h(n)
由于
⌊n1⌋=n
,故:
g(1)S(n)=h(n)−∑i=2ng(i)S(⌊ni⌋)
对
⌊ni⌋
下界分块。使用记忆化搜索就能在
O(n34)
内求出一个前缀和。
为了提高效率,我们还需要结合线性筛,筛出
n23
内的所有
S
值。
这样,我们实现了
O(n23)
求
S(n)
。
复杂度分析需要用到积分方面的知识
,本蒟蒻就不会了。
四、有趣的栗子
来源: BZOJ 3944
https://www.lydsy.com/JudgeOnline/problem.php?id=3944
(1)求
∑ni=1μ(i)
。
我们知道,
μ∗1=e
(
e
为单位元,即
[n=1]
)
于是:
∑i=1nμ(i)=1−∑i=2n∑j=1⌊ni⌋μ(j)
对
⌊ni⌋
下界分块即可。
(2)求
∑ni=1ϕ(i)
。
我们知道,
ϕ∗1=n
。
于是:
∑i=1nϕ(i)=n×(n+1)2−∑i=2n∑j=1⌊ni⌋ϕ(j)
同样下界分块。