P2261 [CQOI2007]余数求和
Posted garen-wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2261 [CQOI2007]余数求和相关的知识,希望对你有一定的参考价值。
我想是人生第一道分块。。。
这道题看上去很简单,暴力随便打,30分拿到手。但是显然你拿30分你就炸了。
我们开始考虑优化。
发现每一个%都是风马牛不相及的,我们考虑转换。
可以发现取膜的性质:
[a mod b = a - b imes lfloor frac{a}{b} floor]
然后这个答案就可以转换为(sum_{i=1}^{n}{k - i imes lfloor frac{k}{i} floor})
用乘法分配律可以把(k)提取,然后问题就是求出(sum{i imes lfloor frac{k}{i} floor})了。
可以发现这个向下取整的东西在一定区间范围内是一样的,我们可以把这些一样的一起算成一遍,这样复杂度一定小于(O(n))。
代码:
#include<cstdio>
#include<algorithm>
long long n, k, ans;
int main()
{
scanf("%lld%lld", &n, &k);
ans = n * k;
long long left = 1, right;
while(left <= n)
{
long long temp = k / left;
if(temp) right = std::min(k / temp, n);
else right = n;
//for(int i = left; i <= right; i++) ans -= i * temp;
long long haha = (left + right) * (right - left + 1) / 2;
ans -= haha * temp;
left = right + 1;
}
printf("%lld
", ans);
return 0;
}
以上是关于P2261 [CQOI2007]余数求和的主要内容,如果未能解决你的问题,请参考以下文章