浅谈整除分块
整除分块是一个挺简单但是应用极广的算法。 听上去挺难,实际不难。 实则它是解决这样一类问题: 求: \[\sum_{i=1}^n \lfloor \frac{n}{i} \rfloor\] 你可能觉得这个式子无法下手,连个 \(\gcd\) 也推不起来。 我们下面证明一个结论: 在 \(\lfloor \frac{n}{1} \rfloor\) , \(\lfloor \frac{n}{2} \rfloor \cdots \lfloor \frac{n}{n} \rfloor\) 中, 不同的数值 最多 有 \(2 \times \sqrt{n}\) 个。 证: 首先, \(i \leq \sqrt{n}\) 的时候,肯定取值不超过 \(\sqrt{n}\) 个。 其次, \(i > \sqrt{n}\) 的时候,会有: \[\lfloor \frac{n}{i} \rfloor < \sqrt{n}\] 这个性质不明白,可以去重学因数了 所以,不同的取值也不超过 \(\sqrt{n}\) 个。(实际不能等于 \(\sqrt{n}\) ,但是我们不在乎这点常数) 所以,总取值不超过 \(2 \times \sqrt{n}\) 个。 这是数学上的说法,在编程上说,我们忽略常数,就说是 \(\sqrt{n}\) 个(指时间级别)。 所以,本题可以迅速解决。 for(int i=1;i<