「学习笔记」 杜教筛
Description
求积性函数前缀和的有力工具,形式化地,对于积性函数 \(f(x)\),求
这里设两个函数 \(g,h\),其中 \(h=f * g\)(狄利克雷卷积),以及 \(S(n)=\sum\limits_{i=1}^n f(i)\)
考察每个 \(g(i)\) 对 \(\rm LHS\) 的贡献有:
提出来第一项就得到了 \(g(1)S(n)\),直接得到下式:
可以整除分块并递归,可以先预处理 \(10^6\) 项,但是主要问题是函数 \(f,g\) 的选择
最基础的是 $\mu * I=\epsilon,\varphi * I=id,(\varphi\times id) * id=id^2 $
复杂度证明
考虑所有递归中出现的 \(n\) 进行求和,大体看做所有 \(\lfloor \frac ni \rfloor\),而每次递归一个 \(n\) 耗费的复杂度是 \(\sqrt n\),那么复杂度写作下式:
加号后的一项总和明显小于加号前的一项的总和,加号前的一项总量为
定积分求解即先提出定量 \(\sqrt n\),求出不定积分上下界的 \(1,(\sqrt n)^{-\frac12+1}\) 再作差
直接做复杂度就是 \(\Theta(n^{\frac 34})\),尝试预处理 \(n^{1-t}\) 的函数前缀和,扩大递归终止条件的范围,这时候缩小积分上界至 \(n^t\) 结果是 \(n^{2t}\),中和一下预处理 \(n^{\frac 13}\) 时复杂度达到了 \(\Theta(n^{\frac 23})\)
个人认为在多数 \(n=10^9\) 的题目中由于记忆化的 std::map
有 \(\log\) 复杂度所以多预处理一些总归是没错的
另外这里的证明方式是考虑的递归总量,那么具体问题中如果涉及了外层套整除分块内次求积性函数区间和,使用杜教筛总复杂度不变
例题
BZOJ3512
考虑对每个 \(\le N\) 的每个 \(n\) 计算 \(\sum\limits_{i=1}^m \varphi(ni)\),尝试展开 \(\varphi(ni)\)
不难根据 \(\varphi\) 函数的定义式,我们只关注每个质数的第一次出现,所以设 \(q\) 为 \(n\) 所有质因子的单次乘积
考虑使用 \(\varphi * I = id\) 改写 \(gcd(i,q)\):
将后两项合并,使用欧拉函数的积性:
发现了 \(S(d,\lfloor\frac md\rfloor)\) 所以可以递归了,记得边界和记忆化,可能的复杂度上界是 \(\Theta(n\sqrt m)\)