[学习笔记] 杜教筛

最近沉迷多项式很久了...突然遇到数论题发现不能不过脑子打出杜教筛了...

几十天前学的这玩意吧...比Min_25筛好理解多了...

式子挺容易推的, 放在这里以备快速查找吧

设我们要计算的是 $S(n)=\sum\limits_{k=1}^nf(k)$, 其中 $f(x)$ 是一个积性数论函数, 则我们构造两个容易求和的积性函数 $h$ 和 $g$, 使它们满足:

$$h=f*g$$

于是我们推一推式子:

$$
\begin {align}
\sum_{i=1}^nh(i)&=\sum_{i=1}^n\sum_{d|i} g(d)f\left(\frac i d\right)\\
&=\sum_{d=1}^ng(d)\sum_{i=1}^{\left\lfloor \frac{n}{d} \right\rfloor}f(i)\\
&=\sum_{d=1}^{n}g(d)\cdot S\left(\left\lfloor \frac n d \right \rfloor \right )\\
&=g(1)\cdot S(n)+\sum_{d=2}^{n}g(d)S\left(\left\lfloor \frac n d \right \rfloor \right )\\\\
g(1)S(n)&=\sum_{i=1}^{n}h(i)-\sum_{d=2}^{n}g(d) S\left(\left\lfloor \frac n d \right \rfloor \right )
\end {align}
$$

数论题的本质就是枚举约数转枚举系数(倍数)

我们容易得到一个结论: 积性数论函数除了 $f(x)=0$ 之外都满足 $f(1)=1$, 于是我们就有了:

$$S(n)=\sum_{i=1}^nh(i)-\sum_{d=2}^ng(d)S\left(\left\lfloor \frac n d \right \rfloor \right )$$

然后递归下去算就可以了. 直接记忆化一下复杂度是 $O(n^{3/4})$ 左右?

其中一个原因大概是因为我们有下式:

$$ \left \lfloor \frac { \left \lfloor \frac n d \right \rfloor} k \right \rfloor = \left \lfloor \frac n {kd} \right \rfloor $$

实际上我们在记忆化的时候也就顺便把所有 $S(\left \lfloor \frac n d \right \rfloor)$ 处的值都求了. 而莫比乌斯反演也刚好用到的是这些值.

优化一下, 用线性筛预处理一下前 $n^{2/3}$ 个点的前缀和, 总复杂度就变成 $O(n^{2/3})$ 了.

记忆化的时候有个技巧, 因为有上面那个除法取整的式子, 所以所有大于 $\sqrt n$ 且需要记忆化的点 $d$ 的 $\left \lfloor \frac n d \right \rfloor$ 值一定都不相等, 直接以下标 $\left \lfloor \frac n d \right \rfloor$ 存就可以了, 不需要Hash表.

posted @ 2019-01-08 10:24  rvalue  阅读(452)  评论(1编辑  收藏  举报