【题解】[CQOI2007] 余数求和 By 5ab as a juruo.
题目信息
题目来源:CCF 重庆省选 2007;
在线评测地址:Luogu#2261;
运行限制:时间不超过 \(1.00\ \textrm{s}\),空间不超过 \(128\ \textrm{MiB}\)。
题目描述
给出正整数 \(n\) 和 \(k\),请计算
其中 \(k\bmod i\) 表示 \(k\) 除以 \(i\) 的余数。
输入格式
输入只有一行两个整数,分别表示 \(n\) 和 \(k\)。
输出格式
输出一行一个整数表示答案。
数据规模与约定
- 对于 \(30\%\) 的数据,保证 \(n,k\le 10^3\);
- 对于 \(60\%\) 的数据,保证 \(n,k\le 10^6\);
- 对于 \(100\%\) 的数据,保证 \(1\le n,k\le 10^9\)。
分析
这道题又是一个十分经典的数论题。
\(60\texttt{ pts}\)
直接暴力乱搞即可。
\(100\texttt{ pts}\)
说实话这道题数据有那么亿点水。
我们来推个式子:
后面那一半是经典的整数分块,直接 \(\mathcal{O}(\sqrt{k})\) 就可以解决。所以这道题的数据范围应该开到 1e14 然后再取模的吧
怎么证明整数分块的复杂度?
对于 \(\left\lfloor\dfrac{k}{i}\right\rfloor\le \sqrt{k}\) 的,值必然最多只有 \(\sqrt{k}\) 个,所以这一部分是 \(\mathcal{O}(\sqrt{k})\) 的。
对于 \(\left\lfloor\dfrac{k}{i}\right\rfloor > \sqrt{k}\) 的,则 \(\dfrac{k}{i}>\sqrt{k}\),可以得到 \(i<\dfrac{k}{\sqrt{k}}=\sqrt{k}\),即这样的数的个数最多只有 \(\sqrt{k}\) 个,一样是 \(\mathcal{O}(\sqrt{k})\) 的。
所以整体的复杂度是 \(\mathcal{O}(\sqrt{k})\)
注意事项
因为特殊的原因,这道题请将所有变量开 long long
,否则会出大问题。
同时,别忘了整数分块中对 \(r\) 变量上界的把握。
Code
#include <cstdio>
using namespace std;
typedef long long ll;
ll my_min(ll a, ll b) { return (a < b)? a:b; } // 最小值函数
int main()
{
ll l, r, n, k, ans;
scanf("%lld%lld", &n, &k); // 输入
ans = 1ll * n * k;
for (l = 1; l <= n; l = r + 1) // 分块
{
if (k / l)
r = my_min(k / (k / l), n); // 别忘了取最小值,否则只有 50 分
else
r = n;
ans -= 1ll * (k / l) * (l + r) * (r - l + 1) / 2; // 统计进去
}
printf("%lld\n", ans); // 输出
return 0; // 然后就 AC 了、
}
本文来自博客园,作者 5ab,转载请注明链接哦 qwq
博客迁移啦,来看看新博客吧 -> https://5ab-juruo.oier.space/