在之前的算法学习中,我们接触了二分查找。今天我们来聊聊另一个高效处理区间问题的利器——前缀和。
这个概念在各类算法竞赛中非常常见,其实理解起来并不复杂。通过构建辅助数组,我们可以将原本需要 O(N) 的区间查询优化到 O(1),核心思想是用空间换时间。
一维前缀和
前缀和(Prefix Sum)是一种预处理数组的方法。通过构建一个辅助数组 s,使得 s[i] 表示原数组 a 前 i 个元素的和。
核心作用: 快速计算任意区间 [l, r] 的和,时间复杂度为 O(1)。
我们先来看一个基础模板题的逻辑。
思路解析
- 预处理:用一个数组
dp[i]表示[1, i]区间内所有元素的和。那么dp[i - 1]存的就是[1, i - 1]区间的和。 递推公式很简单:dp[i] = dp[i - 1] + arr[i] - 查询:当询问区间是
[l, r]时,区间内所有元素的和为:dp[r] - dp[l - 1]。
这题就是很简单的套板子,注意处理一下数据范围,防止溢出。
#include <iostream>
using namespace std;
int main() {
long long a[100861] = {0}, dp[100861] = {0};
int n, q;
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
// 构建前缀和数组
for (int i = 1; i <= n; i++) {
dp[i] = dp[i - 1] + a[i];
}
while (q--) {
int x, y;
cin >> x >> y;
cout << dp[y] - dp[x - 1] << endl;
}
return 0;
}
二维前缀和
类比于一维数组的形式,如果我们能处理出来从 [0, 0] 位置到 [i, j] 位置这片区域内所有元素的累加和,就可以在 O(1) 的时间内,搞定矩阵内任意区域内所有元素的累加和。


