杜教筛学习笔记

杜教筛可以用来在非线性时间内求一个积性函数的前缀和,即 S(n)=i=1nf(i)

前置知识#

积性函数#

积性函数:若有数论函数f对于任意互质整数a,b都有f(ab)=f(a)f(b),则f为积性函数。

完全积性函数:对于任意整数a,bf(ab)=f(a)f(b)的数论函数。

这里列举一些常见的:

  • 积性函数:φ,μ,σ,d

  • 完全积性函数:ϵ,I,id

狄利克雷卷积#

f,g 是两个数论函数,它们的狄利克雷卷积是:

(fg)(n)=d|nf(d)g(nd)

它满足交换律、结合律、分配律

单位元是ϵ,即fϵ=f

这里有几个常用的等式:

μI=ϵφI=idμid=φ

整除分块#

很多反演题目都会有一个这样的形式:i=1nni

对于这个式子,我们可以朴素地进行O(N)的计算。但是很多情况下,这种做法的复杂度是不被允许的。

我们对于每一个n进行打表,发现有大量的值是重复的,而每一个值按顺序排布,呈块状形式,并且每一块的末尾为nni。至此,我们就可以在O(N)的时间内进行计算。

但是上式经常会乘上一些积性函数,这时就可以对积性函数求一个前缀和,每一次跳块也就相当于跳过了这一整段的函数和。

一般的整除分块形式:

for (int l=1,r=0; l<=n; l=r+1) {
	r=n / (n / l);
	// Your Code
}

莫比乌斯反演#

若有

F(n)=dnf(d)

f(n)=dnμ(d)F(nd)=dnμ(nd)F(d)

证明:#

我们用狄利克雷卷积来表示上面的式子,得到F=fI

F卷上μ得到

Fμ=fIμFμ=f(Iμ)=fϵ=ff=Fμ

代入狄利克雷卷积原式:

f(n)=dnμ(d)F(nd)=dnμ(nd)F(d)

证毕。

例题#

Luogu P2398 GCD SUM#

给定n,求

i=1nj=1ngcd(i,j)

做法#

欧拉函数有一个性质:dnφ(d)=n

于是我们可以将原式子套路一下:

i=1nj=1ngcd(i,j)=i=1nj=1ndgcd(i,j)φ(d)=i=1nj=1ndi,djφ(d)

d提到前面去:

=d=1ni=1ndj=1ndφ(d)=d=1nφ(d)ndnd

这样就可以做了。可以用欧拉筛筛出欧拉函数的前缀和,使用整除分块进行优化。

Luogu P2257 YY的GCD#

给定n,m,求

i=1nj=1m[gcd(i,j)Prime]

做法#

我们不知道gcd(i,j)是多少,所以我们枚举它(这里假定nm):

pPrimeni=1nj=1m[gcd(i,j)=p]

同时除以k得到

pPrimeni=1npj=1mp[gcd(i,j)=1]

利用一下μ的性质:dnμ(d)=[n=1]

像上一题那样,把后面替换掉:

pPrimeni=1npj=1mpdgcd(i,j)μ(d)

枚举d,把d提到前面。因为dgcd(i,j),所以i,jd的倍数,把它们上限全都除上d,后面再乘回去,发现个数可直接求,所以去掉两个求和:

pPrimend=1npμ(d)npdmpd

但是这样的复杂度还是过不去。我们继续优化:设T=pd,枚举T,再次提到前面去:

T=1npT,pPrimenTmTμ(Tp)

而后面还是可以预处理+整除分块进行优化。

杜教筛#

一般式#

我们要求i=1nf(i)

用狄利克雷卷积,设有积性函数F,g满足F=fg,记S(n)为上式。如果说我们的F,g都是很容易求的函数,那么我们就可以用它们来求f。那么,我们推一下F的前缀和:

i=1nF(i)=i=1nd|ng(d)f(nd)=d=1ng(d)i=1ndf(i)=d=1ng(d)S(nd)

我们要求的是S(n),所以我们从右式中拆一个出来,即把i=1单独考虑:

i=1nF(i)=g(1)S(n)+d=2ng(d)S(nd)g(1)S(n)=i=1nF(i)d=2ng(d)S(nd)

这就是杜教筛的一般式。

复杂度证明#

首先给出杜教筛的复杂度:

Θ(i=0ni+i=0nni)

积分求近似:

Θ(i=0ni+i=0nni)=Θ(0n(x)dx+0n(nx)dx)=Θ(23n32+n2n12)=Θ(n34)

如果我们预处理前 k 的部分,则可以优化复杂度。当 k=n23 时有理论最优复杂度:

Θ(k+i=0nkni)=Θ(k+0nknxdx)=Θ(k+2nnk)=Θ(k+2nk12)Θ(22nk12)

最后一步是均值不等式,忽略常数后当 k=n23 时取到,原式最小值即为 Θ(n23)

例题#

Luogu P4213 【模板】杜教筛(Sum)#

给定正整数n,求:

ans1=i=1nφ(i)ans2=i=1nμ(i)

做法#

μI=ϵ,很自然想到F=ϵ,g=I,代入原式子即得

S(n)=1d=2nS(nd)

同时,因为φI=id,代入一般式得

S(n)=n(n+1)2d=2nS(nd)

类似地,我们使用整除分块+记忆化搜索解决。但是出杜教筛的题n一般较大,可以手写个 hash 或者直接使用unordered_map解决。

posted @   LewisLi  阅读(239)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩