给出n,k
n>=k都可以直接算的。
那么仅考虑n<k的情况
因为k%i= k-(k/i)*i (取整)
所以,对于多个i值,k/i的结果是一样,所以把这些数放在一起算
k-(k/i1)*i1 k-(k/i2)*i2 k*(k/i3)*i3这些数构成一个等差数列(i逐渐递增)
所以我们可以一次性过掉多个i,而具体过掉多少i,用二分来查找
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
long long n,k,ans=0,now=1,G;
long long findlast(long long l,long long r)
{
if (l==r)return l;
long long mid=l+r>>1;
mid+=1;
if (k/mid==G)return findlast(mid,r);
else return findlast(l,mid-1);
}
int main()
{
scanf("%lld%lld",&n,&k);
if (n>k){ans+=(n-k)*k;n=k;}
while(now<=n)
{
G=k/now;
long long last=findlast(now,n);
ans=ans+(k*2-G*(now+last))*(last-now+1)/2;
now=last+1;
}
printf("%lld\n",ans);
}