[笔记]杜教筛

P1 杜教筛能干什么#

给你一个积性函数 f(i),求 f(i) 的前缀和:

i=1nf(i)

注意,f(i) 必须是积性函数。

P2 怎么杜教筛#

发现直接求不太行,是 O(n) 的,这样只要 n109 就会TLE。

由于满足积性函数,不妨往数论方面想想。

考虑狄利克雷卷积,令 h=fg,其中 g(i) 是我们自己根据要求选的函数。h(n) 可以根据定义算出:

h(n)=dnf(d)g(nd)

再令:

S(n)=i=1nf(i)

现在,我们想求 h(n) 的前缀和:

i=1nh(i)

怎么办?把定义带进去呗:

i=1nh(i)=i=1ndif(d)g(id)

然后发现di 有点难办,所以不妨换一个角度思考。我们考虑 q=jk,qn,然后是不是 jq ,而且贡献是 g(j)f(qj)=g(j)f(k)

好,现在发现凡是 j 的倍数 q 都能产生有关 g(j) 的贡献,而且是先乘后加的。这个时候就要乘法分配律了:

jq,qng(j)f(qj)=g(j)p=1njf(p)

好好好,现在再带回去:

(1)i=1nh(i)=i=1ndif(d)g(id)(2)=i=1ng(i)p=1nif(p)(3)=i=1ng(i)S(ni)

现在呢,我们是不是把这个式子化成了有关于三个函数的形式,而且 g 是我们自己定义的,h 是根据 g 来的,所以实际上啊有两个都被我们捏在手里

是不是只用知道 g(1)S(n) 就可以算出 S(n),那么发现可以运用 h 函数的前缀和联系类似于差分的操作得到:

(4)g(1)S(n)=i=1nh(i)i=2nh(i)(5)=i=1nh(i)i=2ng(i)S(ni)

就得到了核心式子:

g(1)S(n)=i=1nh(i)i=2ng(i)S(ni)

为什么要写成这样呢?你看啊,h 是不是被我们控制,那么我们只用合理设置 g 应该就能很快地算出 h 的前缀和以及 g(i) 的值了。

假设 i=1nh(i)g(i)O(1) 算出,那么是不是只剩下

i=2ng(i)S(ni)

还是未知的,这个时候发现S(ni)非常符合数论分块的形式啊,那我们就可以递归+数论分块解决。

P3 杜教筛例题#

来看一道模板题:【模板】杜教筛

这个时候由于 n109,而杜教筛可以做到 O(n23) 的,所以可以用杜教筛。

先考虑 ans1 怎么算。

直接算 i=1nϕ(i) 肯定不行,于是我们想想它有什么性质:

n=dnϕ(d)

是不是发现可以与一些函数使用狄利克雷卷积了呢?

dnϕ(d)1(nd)=n=id(n)

那么有 ϕ1=id,这个时候直接令 f=ϕ,g=1,h=id 带回去就好了呀:

(6)S(n)=i=1nid(i)i=2nS(ni)(7)=i=1nii=2nS(ni)(8)=n(n+1)2i=2nS(ni)

前面部分 O(1) 求,后面部分数论分块。
再看看 i=1nμ(i)

依旧找性质,考虑莫比乌斯反演:

[n=1]=dnμ(d)

可以得到:

μ1=e

然后可得:

S(n)=1i=2nS(ni)

做完了。

P3 细节#

先算出前面 n23 的前置和,然后利用map进行记忆化搜索。

作者:xmtxlym

出处:https://www.cnblogs.com/xmtxlym/p/17923550.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   小铭同学lym  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示