【整除分块】 余数之和
传送门
题意
给定正整数\(n,k\),计算\((k \; mod\; 1)+(k\; mod\; 2)+(k\; mod\; 3)+\dots +(k\; mod\; n)\)的值,
数据范围
\(1\leq n,k \leq 10^{9}\)
题解
\(k\; mod \; i = k- \lfloor \frac{k}{i} \rfloor \times i\),问题转化为计算\(n\times k - \sum_{i=1}^{n} \lfloor \frac{k}{i}\rfloor \times i\)
证明\(\sum_{i=1}^{n}\left\lfloor\frac{k}{i}\right\rfloor \times i\)最多只有\(2 \sqrt{k}\)个值,
- 当\(i \leq \sqrt{k}\)的时候,最多有\(\sqrt{k}\)个不同的取值
- 当\(i>\sqrt{k}\)的时候,\(\left\lfloor\frac{k}{i}\right\rfloor < \sqrt{k}\) , 故最多有\(\sqrt{k}\)个不同的取值
易知\(\left\lfloor\frac{k}{x}\right\rfloor\)相同的必定是连续的,若某一个相等区间\(x\)是下界,上界是\(\left\lfloor\frac{k}{\left\lfloor\frac{k}{x}\right\rfloor}\right\rfloor\)
证明:
令 \(l = x\),\(r = \left\lfloor\frac{k}{\left\lfloor\frac{k}{x}\right\rfloor}\right\rfloor\), \(\left\lfloor\frac{k}{x}\right\rfloor\)显然随着\(x\)增加减少,
\[\because\left\lfloor\frac{k}{x}\right\rfloor\leq \frac{k}{x},\therefore r \geqslant\left\lfloor\frac{k}{\left(\frac{k}{x}\right)}\right\rfloor=x
\]
\[\therefore\left\lfloor\frac{k}{r}\right\rfloor \leq\left\lfloor\frac{k}{x}\right\rfloor
\]
\[\begin{array}{l}\because r \leq \frac{k}{\left\lfloor\frac{k}{x} \rfloor\right.} , \therefore \left\lfloor\frac{k}{r}\right\rfloor \geqslant\left\lfloor\frac{k}{\frac{k}{\left\lfloor\frac{k}{x}\right\rfloor}}\right\rfloor\end{array}
\]
\[\therefore \left\lfloor\frac{k}{r}\right\rfloor \geqslant x
\]
综上可以得到
\[\left\lfloor \frac{k}{r}\right\rfloor=\left\lfloor\frac{k}{x}\right\rfloor
\]
\[\because i \in\left[x,\left\lfloor\frac{k}{\left\lfloor\frac{k}{x}\right\rfloor}\right\rfloor\right]区间内的数,\lfloor\frac{k}{i}\rfloor的值都相等
\]
时间复杂度:\(O(\sqrt{k})\)
Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll ans;
int main()
{
ll n,k,l,r;
cin>>n>>k;
ans=n*k;
for(l = 1;l<=n;l=r+1)
{
if(k/l == 0) break;//0对答案无贡献
r=min(k/(k/l),n);
ans-=1ll * (k/l) *(l+r)*(r-l+1)/2;//等差数列求和你n*(a1+an)/2
}
cout<<ans<<endl;
}