1 条题解
-
0
这是一个关于在特定时间范围内安排两次测量的问题,其核心在于高效地统计满足特定间隔条件的整数对。
核心要素 描述 问题目标 统计整数对 (i, j)的数量,满足l ≤ i < j ≤ r,且j - i是a的倍数。关键转换 条件 j - i是a的倍数 ⇔j = i + k * a(k≥1)。问题转化为对每个可能的k,计算i的取值范围。核心公式 总对数 = Σk=1K (r - (l + k*a) + 1),其中 K = floor((r-l)/a)。此和式可简化为闭合表达式。推荐算法 数学公式直接计算,复杂度 O(1)。 特殊情形 若最大可能的间隔 K为 0(即r - l < a),则没有满足条件的数对,直接输出 0。🔢 计算步骤与公式推导
-
确定最大倍数
K: 最大的可能间隔k*a不能超过r - l,所以K是(r - l) / a的整数部分,即K = (r - l) / a(向下取整)。 -
计算总方案数: 对于每一个倍数
k(从1到K),i的取值范围是从l到r - k*a。因此,对于这个k,有效的(i, j)对的数量是(r - k*a - l + 1)。 总方案数就是所有这些项的和: 总次数 = Σk=1K (r - l - k*a + 1) -
化简公式(实现关键): 这个求和式可以化简为一个能直接计算的公式: 总次数 = K * (r - l + 1) - a * (K * (K + 1) / 2) 这个公式将复杂度从 O(K) 优化到了 O(1),能够处理
l,r,a高达 10⁹ 的情况。
💻 代码实现思路
#include <iostream> using namespace std; int main() { long long l, r, a; cin >> l >> r >> a; long long K = (r - l) / a; // 计算最大的倍数K if (K <= 0) { cout << 0 << endl; } else { long long total = K * (r - l + 1) - a * (K * (K + 1)) / 2; cout << total << endl; } return 0; }💎 总结
这个问题的关键在于将计数问题转化为等差数列求和,并通过数学推导得到闭合公式,从而避免低效的枚举。
-
- 1
信息
- ID
- 5508
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者