Solution -「CQOI 2007」余数求和

cirnovsky /

☆ 前置知识:整除分块

整除分块就是:

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

这道题让我们求

i=1nk mod i\sum_{i=1}^{n}k\ mod\ i

这个式子可以写成这样

i=1nkki×i\sum_{i=1}^{n}k-\lfloor\frac{k}{i}\rfloor\times i n×ki=1nki×in\times k-\sum_{i=1}^{n}\lfloor\frac{k}{i}\rfloor\times i

我们知道对于每一个整除分块

i=lrki\sum_{i=l}^{r}\lfloor \frac{k}{i} \rfloor

中的值都是一样的,所以我们可以设 T=ki\ T=\lfloor \frac{k}{i} \rfloor

这个式子就变成了

i=lrT×i\sum_{i=l}^{r}T\times i i=lrT×i=lri\sum_{i=l}^{r}T\times\sum_{i=l}^{r}i

至此,我们可以在Ω(N)\Omega(\sqrt{N})的时间内用整除分块解决问题

#include <cstdio>
#define int long long

template < typename T>
inline T getmin(T x, T y) { return x > y ? y : x; }

signed main() {
	long long n, k, ans = 0;
	scanf("%lld %lld", &n, &k);
	for (long long l = 1, r = 0, t; l <= n; l = r + 1) r = (t = k / l) ? getmin(k / t, n) : n, ans -= t * (r - l + 1) * (l + r) >> 1;
	printf("%lld\n", ans = ans + n * k);
}