扩大
缩小

「数论」整除分块

题目

  • 给定正整数 $n$,求如下式子的值:

$$\sum_{i=1}^n \lfloor \frac{n}{i} \rfloor$$

  • 答案对一个数取模,$n \le 10^{15}$,时间限制 2s。

思考

  如果我们暴力求解,复杂度是 $O(n)$ 的,那程序几天也跑不完。

  思考一下,其实我们的瓶颈,就是出于 $i$ 太多了。

  那枚举什么量,才能让枚举的数量变少?

  请看下面这张图,这是一个反比例函数图象的其中一支(图片绘于 desmos):

  我们把 $f(x)=\frac{10^{15}}{x}$,$y=\lfloor f(x) \rfloor$ 的图象画了出来。

  明显地看到,在 $x$ 比较大的时候,$\frac{10^{15}}{x}$ 十分靠近 $x$ 轴。

  这么说明,随着 $x$ 越来越大,相同的 $y$ 的值也会越来越多。

  像 $n=10^{15}$ 的时候,$\frac{10^{15}}{5 \times 10^{14}+1}$ 到 $\frac{10^{15}}{10^{15}}$ 下取整的值都是 1。

  按照刚刚的枚举方法,相当于你有约一半的枚举量都浪费于答案为 1 的情况了。

  那……我们枚举答案

  好办法!

整除分块

  一个数字,最多有多少个因数?

  最理想的状态下,这个数满足:$\forall i \in [1,\sqrt{n}], \ i \mid n$。

  为什么这个数是最理想的,因为如果 $i$ 大于 $\sqrt{n}$,且 $i \mid n$,则 $\frac{n}{i}$ 肯定在 $[1, \sqrt{n}]$ 范围内,必出现过。

  所以这个数就是因数尽可能多的数。

  同时有一个结论,若 $i \mid n$,则 $\frac{n}{i} \mid n$。

  所以,$n$ 的因数个数最多不超过 $2 \times \sqrt{n}$,取整后的不同答案也不会超过 $2 \times \sqrt{n}$。

  因此,不同答案的个数不超过 $2 \times \sqrt{n}$。

  而观察数据范围,$2 \times \sqrt{n}$ 在可以接受的范围内。

  如果能够设计出一种刚好能枚举所有因数的算法,这道题就可以被解决。

  现在来推导一下:

  • 不论 $n$ 取多大,$n$ 一定为它自己的因数,以下以 $n=10$ 为例。
  • 因此,当 $i\in [1,1]$ 时,$\frac{10}{i}$ 答案为 $10$。
  • 接下来让枚举区间左端点设为原右端点 + 1,即 $[2,1]$。
  • 容易得到,这时区间内每个数的答案均为 $\lfloor\frac{10}{2}\rfloor=5$,即为 $a$。
  • 可以得出右端点 $r=\lfloor\frac{10}{5}\rfloor=2$。
  • 此时答案区间为 $[2,2]$,累计为 $a \times (r-l+1)=5$。

 

  • 当区间 $[3,3]$ 计算完毕时,左端点变为 $2+1=3$。
  • 此时区间内每个数答案均为 $\lfloor\frac{10}{3}\rfloor=3$。
  • 可以得出右端点 $r=\lfloor\frac{10}{3}\rfloor=3$。
  • 此时答案区间为 $[3,3]$,累计为 $3 \times (3-3+1)=3$。

 

  • 当区间 $[3,3]$ 计算完毕时,左端点变为 $3+1=4$。
  • 此时区间内每个数答案均为 $\lfloor\frac{10}{4}\rfloor=2$。
  • 可以得出右端点 $r=\lfloor\frac{10}{2}\rfloor=5$。
  • 此时答案区间为 $[4,5]$,累计为 $2 \times (5-4+1)=4$。

 

  • 最后,左端点变为 $5+1=6$。
  • 此时区间内每个数答案均为 $\lfloor\frac{10}{6}\rfloor=1$。
  • 可以得出右端点 $r=\lfloor\frac{10}{1}\rfloor=10$。
  • 此时答案区间为 $[6,10]$,累计为 $1 \times (10-6+1)=5$。
  • 发现右端点已经到 $n$ 了,停止算法。
  • 答案为 $10+5+3+4+5=27$,与 $10+5+3+2+2+1+1+1+1+1=27$ 一致。

  很明显,这个算法将 $\frac{n}{i}$ 相同的情况整合到一块共同处理,效率提高不少。

posted @ 2020-10-09 18:44  HoshizoraZ  阅读(163)  评论(1编辑  收藏  举报