原题
给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的余数。
(sum^n_{i=1}k\%i)
(=sum^n_{i=1}k-lfloor k/i
floor*i)
(=n*k-sum^n_{i=1}lfloor k/i
floor*i)
(lfloor k/i
floor)只有(sqrt k)个取值
证明:
对于所有(>sqrt k)的数,(lfloor k/i
floor)一定是一个对应的(<sqrt k)的值,所以最多只有(2sqrt k)个值
也就是说(lfloor k/i
floor)的取值是这样的:
所以每次i为左端点,k/(k/i)为右端点,这一段就可以直接处理。复杂度为(O(sqrt n))
#include<cstdio>
typedef long long ll;
using namespace std;
int n,k;
ll ans;
int main()
{
scanf("%d%d",&n,&k);
if (n>k) ans=(ll)(n-k)*k,n=k;
int r;
for (int i=1;i<=n;i=r+1)
{
int t=k/i;r=k/t;
if (r>=n) r=n;
ans+=(ll)(r-i+1)*k-(ll)(r-i+1)*(i+r)/2*t;
}
printf("%lld
",ans);
return 0;
}