跳转至

整除分块简介

取整函数引理

不等式转化:

\[ \lfloor x \rfloor \ge k \Longleftrightarrow x \ge k\\ \lfloor x \rfloor < k \Longleftrightarrow x < k\\ \lceil x \rceil > k \Longleftrightarrow x > k\\ \lceil x \rceil \le k \Longleftrightarrow x \le k\\ \]

整除分块

求:

\[ \sum_{i=1}^{m}{\lfloor \frac{n}{i}\rfloor} \]

我们发现,\(\lfloor \frac{n}{i} \rfloor\) 最多只有 \(2\sqrt{n}\) 个值。我们考虑将相同的值一次计算出来。最重要的问题就是知道区间的起点和终点,即

\[ \begin{align*} l&=\min_{\lfloor \frac{n}{i}\rfloor = k}{\{i\}}\\ r&=\max_{\lfloor \frac{n}{i}\rfloor = k}{\{i\}} \end{align*} \]

我们用 \(l_i\)\(r_i\) 表示第 \(i\) 段区间的左右边界。容易发现,对于 \(i>1\)\(l_i=r_{i-1}+1\)。又因为 \(l_1=1\),我们只要知道前一个区间的右边界,就能知道当前的左边界了。

假设我们已知 \(l_i\),要求出 \(r_i\)

\(k=\lfloor \frac{n}{l_i} \rfloor\)\(r_i\) 为使 \(\lfloor \frac{n}{r_i} \rfloor \ge k\) 的最大值。 我们注意到 \(\lfloor \frac{n}{r_i} \rfloor \ge k\) 等价于

\[ \frac{n}{r_i} \ge k \]

从而

\[ r_i\le \frac{n}{k} \]

因为 \(r_i\) 是整数,因此 \(r_i = \lfloor \frac{n}{k}\rfloor\),即

\[ r_i=\left\lfloor{\frac{n}{\lfloor \frac{n}{l_i} \rfloor}}\right\rfloor \]

写一个 for 循环,循环求出 \(l_i\) 对应的 \(r_i\),更新答案,并使 \(l_{i+1}=r_i+1\)

时间复杂度 \(O(\sqrt{n})\)