具体代码如下(有详细注释和思想):
#include <bits/stdc++.h>
using namespace std;
int n, m, l, r; // n:数组长度,m:查询次数,l和r:每次查询的区间左右端点
int a[100010], s[100010]; // a数组存储原始数据,s数组为前缀和数组
/*
代码思路解析:
1. 前缀和预处理:
- 构建前缀和数组s,使得s[i]表示数组a前i个元素的和。
- 通过递推公式s[i] = s[i-1] + a[i],时间复杂度O(n)。
2. 查询优化:
- 每次查询区间和[l, r]时,直接计算s[r] - s[l-1],时间复杂度O(1)。
- 避免了暴力遍历区间求和导致的O(n)时间复杂度,显著提升效率。
关键点:
- 数组下标从1开始,使得s[0] = 0,处理区间左端点l=1时不会越界。
- 前缀和思想将区间和查询的时间复杂度从O(m*n)降低到O(n + m),适用于大规模查询场景。
*/
int main() {
// 输入数组长度n和查询次数m
cin >> n >> m;
// 读取数组a的元素,注意下标从1开始(方便前缀和计算)
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
// 计算前缀和数组s,s[i]表示a[1]到a[i]的和
// 例如:s[3] = a[1] + a[2] + a[3]
// 通过递推公式s[i] = s[i-1] + a[i]高效计算
for (int i = 1; i <= n; i++) {
s[i] = s[i - 1] + a[i];
}
// 处理每个查询
while (m--) {
cin >> l >> r; // 读取当前查询的区间[l, r]
// 利用前缀和快速计算区间和:s[r] - s[l-1]
// 例如:区间[2,4]的和 = s[4] - s[1] = (a1+a2+a3+a4) - (a1) = a2+a3+a4
cout << s[r] - s[l - 1] << endl;
}
return 0;
}
此篇文章参考了acwing算法基础课。