题意
根据题目给的代码,不难看出这是让我们求:
\(\sum\limits_{i=1}^{n}\lfloor \frac{n}{i}\rfloor\)
题解
整除分块模板题。
一看数据范围,发现用暴力肯定会超时。我们发现加数中有许多是相同的,并且这些加数单调不增(即相同加数必定在一起)。如果找出每段相同加数的长度,就能很快得到答案。
也就是说,如果对于一个 \(i\),能找出最大的 \(j\) 使得 \(\lfloor \frac{n}{i}\rfloor=\lfloor\frac{n}{j}\rfloor\)
,这一段的和即为 \(\lfloor\frac{n}{i}\rfloor(j-i+1)\)。
根据向下取整的性质,可得 \(\lfloor \frac{n}{i}\rfloor\le\frac{n}{j}<\lfloor \frac{n}{i}\rfloor+1\);
将前一个不等式变形,得 \(j\le \frac{n}{\lfloor \frac{n}{i}\rfloor}\);
由于 \(j\) 是正整数,可得 \(j\le \lfloor\frac{n}{\lfloor \frac{n}{i}\rfloor}\rfloor\);
所以 \(j\) 最大为 \(\big\lfloor\frac{n}{\lfloor \frac{n}{i}\rfloor}\big\rfloor\)。
时间复杂度为 \(\mathcal{O}(\sqrt n)\)。证明如下:
-
当 \(1\le i\le \sqrt n\) 时:\(i\) 的取值有 \(\sqrt n\) 种,所以此时 \(\lfloor\frac{n}{i}\rfloor\) 的取值最多有 \(\sqrt n\) 种。
-
当 \(\sqrt n< i\le n\) 时:\(1\le\lfloor\frac{n}{i}\rfloor\le\sqrt n\),所以 \(\lfloor\frac{n}{i}\rfloor\) 的取值最多有 \(\sqrt n\) 种。
也就是说,\(\lfloor\frac{n}{i}\rfloor\) 的取值最多有 \(2\sqrt n\) 种,所以时间复杂度为 \(\mathcal{O}(\sqrt n)\)。
\(T\) 组数据,时间复杂度 \(\mathcal{O}(T\sqrt n)\)
代码:
q = read();
for(; q; --q) {
ans = 0;
n = read();
for(i = 1; i <= n; i = j + 1) {
j = n / (n / i);
ans += (j - i + 1) * (n / i);
}
printf("%lld\n", ans);
}