题目描述
给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值。
题解
很不错的一道题。
由于我们有
amodb=a−floor(a/b)∗b;
a
m
o
d
b
=
a
−
f
l
o
o
r
(
a
/
b
)
∗
b
;
对于floor(a/b)相等的等差数列,我们就可以除法分块来进行计算了;
复杂度
O(n‾√)
O
(
n
)
/*
a%b= a-floor(a/b)*b;//对于a/b相等的等差数列,然后分块;
除法分块;
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<set>
#define rep(a,b,c) for(register int a=b;a<=c;a++)
using namespace std;
typedef long long ll;
ll n,k;
const int N=1e9+10;
int main()
{
register ll ans=0;
scanf("%lld %lld",&n,&k);
if(n>k){
ans=1ll*k*(n-k);
n=k;
}
ans+=n*k;
register ll l=1,r=0;
for(l=1;l<=n;l=r+1)
{
if(k/l!=0) r=min(k/(k/l),n);//上界是 (k/(k/l)) l为左端点,要使商(k/l)一定的右端点一定是 r 刚好整除 k
else r=n;
ans-=(k/l)*(r-l+1)*(l+r)/2;
}
printf("%lld\n",ans);
return 0;
}