1. 程式人生 > >[學習筆記] 杜教篩

[學習筆記] 杜教篩

mit 記憶 text 快速查找 floor 相等 sqrt limit 原因

幾十天前學的這玩意吧...比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表.

[學習筆記] 杜教篩