Description
给出正整数(n)和(k),计算(j(n, k)=k;mod;1;+;k;mod;2;+;k;mod;3;+;…;+;k;mod;n)的值,其中(k;mod;i)表示(k)除以(i)的余数。例如(j(5, 3)=3;mod;1;+;3;mod;2;+;3;mod;3;+;3;mod;4;+;3;mod;5=0+1+0+3+3=7)
Input
输入仅一行,包含两个整数(n, k)。
Output
输出仅一行,即(j(n, k))。
Sample Input
5 3
Sample Output
7
HINT
(50\%)的数据满足:(1 le n, k le 1000)。
(100\%)的数据满足:(1 le n ,k le 10^{9})。
(n;mod;i=n-i imes lfloor frac{n}{i} floor),因此我们可以对(lfloor frac{n}{i} floor)相同的值的一块进行分块((sqrt{n})块)。
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
typedef long long ll;
inline ll sum(ll a,ll b) { return (a+b)*(b-a+1)>>1; }
inline ll calc(ll n,ll m)
{
ll ret = 0;
if (m > n) ret = (m-n)*n,m = n;
ll pos;
for (ll i = 1;i <= m;i = pos+1)
{
pos = min(n/(n/i),m);
ret += (pos-i+1)*n-sum(i,pos)*(n/i);
}
return ret;
}
int main()
{
freopen("1257.in","r",stdin);
freopen("1257.out","w",stdout);
ll n,m;
scanf("%lld %lld",&m,&n);
printf("%lld",calc(n,m));
fclose(stdin); fclose(stdout);
return 0;
}