【整除分塊】 餘數之和
阿新 • • 發佈:2020-08-01
傳送門
題意
給定正整數\(n,k\),計算\((k \; mod\; 1)+(k\; mod\; 2)+(k\; mod\; 3)+\dots +(k\; mod\; n)\)的值,
資料範圍
\(1\leq n,k \leq 10^{9}\)
題解
證明\(\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}\)
易知\(\left\lfloor\frac{k}{x}\right\rfloor\)相同的必定是連續的,若某一個相等區間\(x\)是下界,上界是\(\left\lfloor\frac{k}{\left\lfloor\frac{k}{x}\right\rfloor}\right\rfloor\)
時間複雜度:\(O(\sqrt{k})\),
證明:
令 \(l = x\),\(r = \left\lfloor\frac{k}{\left\lfloor\frac{k}{x}\right\rfloor}\right\rfloor\), \(\left\lfloor\frac{k}{x}\right\rfloor\)
\(\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\)的值都相等
Code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
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-=(ll) (k/l) *(l+r) *(r-l+1)/2;//等差數列
}
cout<<ans<<endl;
}
時間複雜度\(O(\sqrt{k})\)