正题
杜教筛是用来解决某些积性函数求前缀和的问题的。
例如求 ∑i=1nμ(i)\sum_{i=1}^n \mu(i)∑i=1nμ(i) 或者 ∑i=1nφ(i)\sum_{i=1}^n \varphi(i)∑i=1nφ(i) 。
下面我们以 ∑i=1nμ(i)\sum_{i=1}^n \mu(i)∑i=1nμ(i) 为例子,详细说说杜教筛到底是如何运作的。
有 μ∗1=e\mu * 1=eμ∗1=e ,那么可以得到 :1=∑i=1ne(i)=∑i=1nμ(i)∑j=1⌊ni⌋1(j)=∑i=1n∑j=1⌊ni⌋μ(j)=∑i=1nF(⌊ni⌋) 1=\sum_{i=1}^ne(i)=\sum_{i=1}^n \mu(i) \sum_{j=1}^{\lfloor \frac n i \rfloor} 1(j)=\sum_{i=1}^n \sum_{j=1}^{\lfloor\frac n i \rfloor}\mu(j)=\sum_{i=1}^n F(\lfloor \frac n i\rfloor) 1=i=1∑ne(i)=i=1∑nμ(i)j=1∑⌊in⌋1(j)=i=1∑nj=1∑⌊in⌋μ(j)=i=1∑nF(⌊in⌋)
可以推出:F(n)=1−∑i=1n−1F(⌊ni⌋) F(n)=1-\sum_{i=1}^{n-1} F(\lfloor \frac n i \rfloor) F(n)=1−i=1∑n−1F(⌊in⌋)
可以发现,只需要我们知道所有 F(⌊ni⌋)F(\lfloor \frac n i \rfloor)F(⌊in⌋) 的前缀和,就可以知道花费 O(n)O(\sqrt n)O(n) 的时间就可以知道 F(n)F(n)F(n) 的前缀和。
另外,还有式子 ⌊⌊ni⌋j⌋=⌊nij⌋\lfloor \frac {\lfloor \frac n i \rfloor} j \rfloor=\lfloor \frac n {ij} \rfloor⌊j⌊in⌋⌋=⌊ijn⌋,所以递归做的话,总共要求的不同的前缀和一共有 O(n)O(\sqrt n)O(n) 个。
时间复杂度便是 ∑i=1ni+ni\sum_{i=1}^{\sqrt n}\sqrt i+\sqrt{\frac n i}∑i=1ni+in。
由于前面必然小于后面,所以我们先将前面忽视。
∑i=1nni≤∫0nnidi=2n34\sum_{i=1}^{\sqrt n}\sqrt{\frac n i}\leq \int_{0}^{\sqrt n}\sqrt{\frac n i}di=2n^{\frac 3 4}∑i=1nin≤∫0nindi=2n43
发现这样还是好慢,考虑≤B\leq B≤B的前缀和直接预处理,那么时间复杂度就变为 B+∑i=1nBni≤∫0nBnidi=O(B+nB)B+\sum_{i=1}^{\frac n B}\sqrt{\frac n i}\leq \int_0^{\frac n B} \sqrt{\frac n i}di=O(B+\frac{n}{\sqrt B})B+∑i=1Bnin≤∫0Bnindi=O(B+Bn) ,容易知道当 B=O(n23)B=O(n^{\frac 2 3})B=O(n32) 时有最优复杂度 O(n23)O(n^{\frac 2 3})O(n32)。
总结上述步骤,我们发现,可以使用杜教筛来求解积性函数 fff 前缀和当且仅当:
1.存在 g,hg,hg,h ,满足 f∗g=hf*g=hf∗g=h
2. 时间复杂度实际上是 g,hg,hg,h 求解关键点(即 ni\frac n iin )前缀和的时间与 n23n^{\frac 2 3}n32 取 max\maxmax。
26万+

被折叠的 条评论
为什么被折叠?



