2 条题解
-
1
问题分析
这是一个典型的区间和查询问题,核心需求是高效处理大量的区间求和查询。由于
n和m都高达 10⁵,若每次查询都暴力累加(时间复杂度 O(n)),总时间复杂度会达到 O(n*m) = 10¹⁰,远超时间限制。最优解决方案是使用前缀和数组:
- 预处理一个前缀和数组
prefix,其中prefix[i]表示前i段路程的总时间; - 对于任意查询
[l, r],区间和 =prefix[r] - prefix[l-1]; - 预处理时间复杂度 O(n),单次查询时间复杂度 O(1),总时间复杂度 O(n + m),完全满足 10⁵ 级别的数据规模。
完整C++代码实现
#include <iostream> #include <vector> using namespace std; int main() { // 关闭同步加速cin/cout,避免大数据量下超时 ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; // 前缀和数组:prefix[0] = 0,prefix[1] = a1,prefix[2] = a1+a2,... vector<long long> prefix(n + 1, 0); // 用long long防止溢出 for (int i = 1; i <= n; ++i) { int time; cin >> time; prefix[i] = prefix[i - 1] + time; } int m; cin >> m; while (m--) { int l, r; cin >> l >> r; // 区间[l, r]的和 = 前r项和 - 前l-1项和 cout << prefix[r] - prefix[l - 1] << '\n'; // 用'\n'代替endl,减少刷新缓冲区开销 } return 0; }代码详细解释
1. 输入输出优化(关键!)
ios::sync_with_stdio(false); cin.tie(nullptr);ios::sync_with_stdio(false):关闭 C++ 标准输入输出与 C 标准输入输出的同步,大幅提升 cin/cout 速度;cin.tie(nullptr):解除 cin 与 cout 的绑定(默认 cin 读取前会刷新 cout),进一步加速;- 用
'\n'代替endl:endl会强制刷新输出缓冲区,而'\n'仅输出换行,效率更高。
2. 前缀和数组设计
- 前缀和数组
prefix长度为n+1,且prefix[0] = 0:- 这样设计可以统一处理
l=1的情况(如查询[1, r]时,直接用prefix[r] - prefix[0]); - 避免单独判断边界,简化逻辑。
- 这样设计可以统一处理
- 数据类型选择
long long:- 最坏情况下,
n=10⁵,每个a_i=1000,总和 = 10⁵ * 1000 = 10⁸,虽然 int(最大约 2×10⁹)能容纳,但为了绝对避免溢出(如数据范围扩展),优先使用long long。
- 最坏情况下,
3. 核心逻辑
- 预处理前缀和:
遍历输入的每一段路程时间,累加得到前缀和数组。prefix[i] = prefix[i - 1] + time; - 处理查询:
例如查询cout << prefix[r] - prefix[l - 1] << '\n';[2,4]:prefix[4] = a1+a2+a3+a4;prefix[1] = a1;- 差值 =
a2+a3+a4,即目标区间和。
测试用例验证(样例1)
输入:
5 1 2 3 4 5 3 1 3 2 5 1 5前缀和数组计算:
prefix[0] = 0prefix[1] = 0 + 1 = 1prefix[2] = 1 + 2 = 3prefix[3] = 3 + 3 = 6prefix[4] = 6 + 4 = 10prefix[5] = 10 + 5 = 15
查询处理:
l=1, r=3→prefix[3] - prefix[0] = 6 - 0 = 6;l=2, r=5→prefix[5] - prefix[1] = 15 - 1 = 14;l=1, r=5→prefix[5] - prefix[0] = 15 - 0 = 15; 输出结果与样例一致。
边界情况测试
- 单段路程查询:
n=1, a=[5], m=1, l=1, r=1→ 输出5; - 全区间查询:
n=10⁵,查询l=1, r=10⁵→ 直接返回prefix[10⁵]; - 相邻区间查询:
l=r-1→ 如l=3, r=4,返回a3+a4。
总结
- 核心思路:用前缀和数组将区间和查询从 O(n) 优化到 O(1),解决大数据量下的效率问题;
- 关键优化:关闭 cin/cout 同步、使用
long long防溢出、用'\n'代替endl; - 核心公式:区间
[l, r]的和 = 前缀和数组prefix[r] - prefix[l-1]。
该方案是区间和查询的最优解,时间/空间复杂度均为线性,能稳定处理题目要求的 10⁵ 级数据。
- 预处理一个前缀和数组
- 1
信息
- ID
- 597
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 34
- 已通过
- 8
- 上传者