最近沉迷多項式好久了...忽然遇到數論題發現不能不過腦子打出杜教篩了...函數
幾十天前學的這玩意吧...比Min_25篩好理解多了...優化
式子挺容易推的, 放在這裏以備快速查找吧spa
設咱們要計算的是 $S(n)=\sum\limits_{k=1}^nf(k)$, 其中 $f(x)$ 是一個積性數論函數, 則咱們構造兩個容易求和的積性函數 $h$ 和 $g$, 使它們知足:遞歸
$$h=f*g$$it
因而咱們推一推式子:io
$$
\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}
$$技巧
數論題的本質就是枚舉約數轉枚舉係數(倍數)im
咱們容易獲得一個結論: 積性數論函數除了 $f(x)=0$ 以外都知足 $f(1)=1$, 因而咱們就有了:co
$$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表.