整数分块学习笔记

整数分块学习笔记

——by sunzz3183


引入

\[\sum\limits_{i=1}^{n}\left \lfloor \frac{n}{i} \right \rfloor \]

正常求法:

直接枚举每个 \(n\),时间复杂度为 \(O(n)\)

可是,如果 \(1\leq n \leq 10^8\) 呢?

所以,我们要用到分块的思想:整数分块

整数分块

显然

\[\exists 1\leq l\leq r \leq n,\left \lfloor \frac{n}{i}\right \rfloor =\left \lfloor \frac{n}{j}\right \rfloor (l\leq i,j\leq r) \]

我们会浪费很多的时间。

那么,有多少段相等呢?

我们来看一张图

显然,存在一个 \(k\) 使得

\[\left \lfloor \frac{n}{l} \right \rfloor =k \]

并让

\[r=\left \lfloor \frac {n}{k }\right \rfloor \]

\[\left \lfloor \frac{n}{i}\right \rfloor =\left \lfloor \frac{n}{j}\right \rfloor (l\leq i,j\leq r) \]

而显然 \(k\) 是由 \(l\) 得到,\(r\) 是由 \(k\) 得到。

所以,我们去枚举 \(l\),并让 \(k,r\) 等于上面的东西。

而下一段区间的 \(l\)\(r+1\)

每一段的值为

\[\left \lfloor \frac{n}{l} \right \rfloor (r-l+1) \]

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

代码

int division_block(int n){
   int sum=0;
   for(int l=1,r;l<=n;l=r+1)
       r=n/(n/l),sum+=n/l*(r-l+1);
   return sum;
}
posted @ 2023-03-08 07:06  sunzz3183  阅读(27)  评论(0编辑  收藏  举报
Live2D