标签:复杂度 复杂 一个 include play math cst 乘法 一起
这道题看上去很简单,暴力随便打,30分拿到手。但是显然你拿30分你就炸了。
我们开始考虑优化。
发现每一个%都是风马牛不相及的,我们考虑转换。
可以发现取膜的性质:
\[a \mod b = a - b \times \lfloor \frac{a}{b}\rfloor\]
然后这个答案就可以转换为\(\sum_{i=1}^{n}{k - i \times \lfloor \frac{k}{i}\rfloor}\)
用乘法分配律可以把\(k\)提取,然后问题就是求出\(\sum{i \times \lfloor \frac{k}{i}\rfloor}\)了。
可以发现这个向下取整的东西在一定区间范围内是一样的,我们可以把这些一样的一起算成一遍,这样复杂度一定小于\(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\n", ans);
return 0;
}
标签:复杂度 复杂 一个 include play math cst 乘法 一起
原文地址:https://www.cnblogs.com/Garen-Wang/p/9551445.html