BZOJ 1257 余数之和

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;
}
原文地址:https://www.cnblogs.com/mmlz/p/4321007.html