ans = 0;
for(int l = 1, r; l <= n; l = r + 1)
{
r = n / (n / l);
ans += n / l * (r - l + 1);
}
分块后我们发现每一块 然后去计算就行
公差为k/left
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n, k, ans = 0;
long long left = 1, right, rest;
scanf("%lld%lld", &n, &k);
while (left <= n && left <= k)
{
right = min(k / (k / left), n);
rest = k % left;
ans += (rest + rest - (right - left) * (k / left)) * (right - left + 1) / 2;
left = right + 1;
}
if (n > k)
{
ans += k * (n - k);
}
cout << ans;
}
[数论分块运用](https:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
int f(int t)
{
return n-m+(m-1)/t*t;
}
int B(int st,int ed,int num)
{
int ans=1e8;
int r=0;
ed=min(ed,num);
for(int i=st;i<=ed;i=r+1)
{
r= min(ed,num/(num/i));
if(f(i)>=0)
{
ans=min(ans,f(i));
}
}
return ans;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
if(n>=m)cout<<abs(n-m)<<endl;
else if(m%n==0)cout<<0<<endl;
else cout<<B(1,n,m-1)<<endl;
}
}