#include <iostream>
#include <vector>
using namespace std;
// 构建前缀和并处理查询的模板
int main() {
int n, q; // n:数组长度,q:查询次数
cin >> n >> q;
// 1. 读入原始数组(0-based)
vector<long long> nums(n); // 用long long避免大数溢出
for (int i = 0; i < n; ++i) {
cin >> nums[i];
}
// 2. 构建前缀和数组(prefix[0] = 0,prefix[i] = sum(nums[0..i-1]))
vector<long long> prefix(n + 1, 0);
for (int i = 1; i <= n; ++i) {
prefix[i] = prefix[i - 1] + nums[i - 1]; // 累加前i-1个元素
}
// 3. 处理每个查询(查询[l, r]为1-based)
while (q--) {
int l, r;
cin >> l >> r;
// 区间和 = prefix[r] - prefix[l-1]
cout << prefix[r] - prefix[l - 1] << endl;
}
return 0;
}
经典:
✅ 一维前缀和模板(Prefix Sum - 1D)
💡 适用场景:快速求任意区间 [l, r] 的和
🔹 模板代码:
// 输入:长度为 n 的数组 a[0..n-1]
vector<int> a(n);
for (int i = 0; i < n; ++i) cin >> a[i];
// 构建前缀和数组 s[0..n]
// s[i] 表示前 i 个数的和(不包含第 i 个)
vector<long long> s(n + 1, 0);
for (int i = 1; i <= n; ++i) {
s[i] = s[i - 1] + a[i - 1];
}
// 查询区间 [l, r](下标从 0 开始)
int l, r; // 输入:0 <= l <= r < n
long long sum = s[r + 1] - s[l]; // 区间和
✅ 二维前缀和模板(2D Prefix Sum)
💡 适用场景:求一个二维矩形区域内所有元素的和
🔹 模板代码:
// 输入:矩阵 a[n][m]
vector<vector<int>> a(n, vector<int>(m));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> a[i][j];
// 构建二维前缀和 s[n+1][m+1]
vector<vector<long long>> s(n + 1, vector<long long>(m + 1, 0));
// 注意:s[i][j] 表示从 a[0][0] 到 a[i-1][j-1] 的区域和
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
s[i][j] = s[i - 1][j] + s[i][j - 1]
- s[i - 1][j - 1] + a[i - 1][j - 1];
}
}
🔹 查询某一子矩阵 [x1, y1] 到 [x2, y2](0-based,包含端点):
// 因为前缀和数组是从 1 开始,所以 +1
long long sum = s[x2 + 1][y2 + 1]
- s[x1][y2 + 1]
- s[x2 + 1][y1]
+ s[x1][y1];

京公网安备 11010502036488号