杜教筛

杜教筛

f(x) 为某个积性函数,s(n)=i=1nf(i),我们构造另一干函数 gfg 的前缀和。

i=1n(fg)(i)=i=1nd|ig(d)f(id)=d=1ng(d)i=1ndf(i)=d=1ng(d)s(nd)

我们的目标是 s(n)

我们发现:

g(1)s(n)=i=1n(fg)(i)d=2ng(d)s(nd)

我们需要算出 (fg) 的前缀和,通过对减号右边数论分块,我们需要算 g 的前缀和,我们还需要算出 g(1) 。所以关键在于 g 函数的选取。

例子

  • i=1Nμ(i)

不难发现我们这里应该选 g 函数为 I 。然后 g 的前缀和为 nfg 的前缀和是 1

  • i=1Nϕ(i)

不难发现我们还是选 gI。然后 g 的前缀和为 nfg 的前缀和为 n(n+1)2

  • i=1Nϕ(i)×i

考虑有:

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

考虑把 d 消掉,所以我们不妨令 g=id,这样这个题就结束了。

  • i=1Nϕ(i)×i2

我们还是和上面一样,把它拆开:

(fg)(n)=d|nf(d)g(nd)=d|nϕ(d)×d2×g(nd)

我们本着把 d2 消去的思路,不妨令 g(x)=x2,这样就可以了。

复杂度证明

k 以前的部分我们预处理,所以杜教筛的复杂度为:

i=1nkni1nknx12dx=O(nk)

所以总复杂度应该为 O(nk+k),显然 k=n23 的时候最优,所以总复杂度为 O(n23)

相反,如果不预处理的话,相当于要对所有可能的 ni 做一个整数分块,一共有 O(n) 种取值,我们不妨认为这 O(n) 种取值为 n1,n2,,nn,实际上,整数分块得到的数不会超过 2n 个,用这 n 个最大的值来估算显然是正确的。

所以时间复杂度约为:

1nnxdx=O(n34)

posted @   NuclearReactor  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示
主题色彩