杜教篩
前置知識:熟悉 狄利克雷卷積
。
這個東西是用來快速求出積性函式的某個字首和,時間複雜度大概是 \(O(n^{\frac{2}{3}})\) 。
假定要求的是 \(\sum_{i=1}^{n}f(i)\) ,現在要找到另一個積性函式 \(g\) 把它們捲起來,得到 \(h=f*g\) 。
然後就是一大波變式。
設 \(S(n) = \sum_{i=1}^{n}f(i)\) 。
\[\begin{aligned} \sum_{i=1}^{n}h(i) &= \sum_{i=1}^{n} \sum_{d|i} f(d) \times g(\frac{i}{d}) \\ &= \sum_{i=1}^{n} \sum_{d|i} g(d) \times f(\frac{i}{d}) \\ &= \sum_{d=1}^{n} \sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}g(d) \times f(i) \\ &= \sum_{d=1}^{n}g(d) \sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}f(i) \\ &= \sum_{d=1}^{n}g(d) S(\lfloor \frac{n}{d} \rfloor) \end{aligned}\]
當 \(d=1\) 時,\(\lfloor \frac{n}{d} \rfloor=n\) ,正好是要求的,所以把它單獨分出來。
\[\sum_{i=1}^{n}h(i) = g(1)S(n) + \sum_{d=2}^{n}g(d) S(\lfloor \frac{n}{d} \rfloor) \]
則
\[g(1)S(n) = \sum_{i=1}^{n}h(i) - \sum_{d=2}^{n}g(d) S(\lfloor \frac{n}{d} \rfloor) \]
如果能快速求出右邊式子的值,就知道 \(S(n)\) 了。
所以要找到合適的 \(g\) ,使得 \(h\) 和 \(g\)
先假定上式的 \(h\) 和 \(g\) 的值能 \(O(1)\) 算出。
負號右邊用整除分塊求值,但是 \(\lfloor \frac{n}{d} \rfloor\) 最大才縮小了一半,還是不能直接求,所以遞迴求解。