题目链接:余数之和
题意:给定正整数$n$和$k$,计算$k\%1+k\%2+\dots+k\%n$的值
思路:因为$k\%i=k-\left \lfloor \frac{k}{i} \right \rfloor * i$,所以问题就转换为计算$n*k-\sum _{i=1}^{n}\left \lfloor \frac{k}{i} \right \rfloor*i$
在某一段区间$(l,r)$内$\left \lfloor \frac{k}{i} \right \rfloor$的值是相等的,并且等于$\left \lfloor \frac{k}{l} \right \rfloor$,其中$r=\left \lfloor \frac{k}{\left \lfloor \frac{k}{l} \right \rfloor} \right \rfloor$
证明:设$g(x)=\left \lfloor \frac{k}{\left \lfloor \frac{k}{x} \right \rfloor} \right \rfloor$
因为
$$\left \lfloor \frac{k}{x} \right \rfloor\leq \frac{k}{x}$$
所以
$$\left \lfloor \frac{k}{\left \lfloor \frac{k}{x} \right \rfloor} \right \rfloor\geq \left \lfloor \frac{k}{\frac{k}{x}} \right \rfloor=x$$
即$g(x)\geq x$,于是有
$$\left \lfloor \frac{k}{g(x)} \right \rfloor\leq \left \lfloor \frac{k}{x} \right \rfloor\tag{1}$$
又因为
$$\left \lfloor \frac{k}{\left \lfloor \frac{k}{x} \right \rfloor} \right \rfloor\leq \frac{k}{\left \lfloor \frac{k}{x} \right \rfloor}$$
所以
$$\frac{k}{\left \lfloor \frac{k}{\left \lfloor \frac{k}{x} \right \rfloor} \right \rfloor}\geq \frac{k}{\frac{k}{\left \lfloor \frac{k}{x} \right \rfloor}}=\left \lfloor \frac{k}{x} \right \rfloor$$
即
$$\left \lfloor \frac{k}{g(x)} \right \rfloor\geq \left \lfloor \frac{k}{x} \right \rfloor\tag{2}$$
由$(1)(2)$得
$$\left \lfloor \frac{k}{g(x)} \right \rfloor= \left \lfloor \frac{k}{x} \right \rfloor$$
所以在$i\in[x,g(x)]$范围内,有$\left \lfloor \frac{k}{i} \right \rfloor$的值都相等,即$r=\left \lfloor \frac{k}{\left \lfloor \frac{k}{l} \right \rfloor} \right \rfloor$
在求$\sum _{i=1}^{n}\left \lfloor \frac{k}{i} \right \rfloor*i$时,可以分为一块一块来求,对于每一块,把$\left \lfloor \frac{k}{l} \right \rfloor$,然后利用等差数列求和公式求出$\sum _{i=l}^{r}i$即可。
#include <iostream>
#include <algorithm>
#include <cstdio> using namespace std; typedef long long ll; ll n, k; int main()
{
scanf("%lld%lld", &n, &k);
ll res = n * k;
for (ll l = , r = ; l <= n; l = r + ) {
if (k / l) r = min(k / (k / l), n);
else r = n;
res -= (k / l) * (r - l + ) * (l + r) / ;
}
printf("%lld\n", res);
return ;
}