前缀和

682 字
3 分钟
前缀和

前缀和#

前缀和用来快速求区间和。它的核心是提前做一次预处理,把“每次都遍历区间”变成“两个数组值相减”。

1、为什么需要前缀和#

假设有数组:

1 2 3 4 5

如果想求 [2, 4] 的和,也就是:

2 + 3 + 4 = 9

普通做法是每次循环一遍区间,复杂度是 O(n)。

如果有很多次查询,这样会很慢。前缀和可以把每次查询降到 O(1)。

2、一维前缀和公式#

定义:

s[i] = a[1] + a[2] + ... + a[i]

那么:

s[i] = s[i - 1] + a[i]

查询 [l, r] 的区间和:

a[l] + ... + a[r] = s[r] - s[l - 1]

3、一维前缀和模板#

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m;
int a[N], s[N];
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++) {
s[i] = s[i - 1] + a[i];
}
while (m--) {
int l, r;
scanf("%d%d", &l, &r);
printf("%d\n", s[r] - s[l - 1]);
}
return 0;
}

这里建议数组从 1 开始存,这样 s[l - 1] 更自然。

4、二维前缀和解决什么问题#

二维前缀和用于快速求一个子矩阵的和。

比如矩阵里要查询左上角 (x1, y1) 到右下角 (x2, y2) 这个矩形区域的总和。

5、二维前缀和公式#

构造公式:

s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j]

查询公式:

sum = s[x2][y2]
- s[x1 - 1][y2]
- s[x2][y1 - 1]
+ s[x1 - 1][y1 - 1]

可以理解为:先取大矩形,再减掉上面和左边多算的部分,最后把左上角被减了两次的区域加回来。

6、二维前缀和模板#

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m, q;
int a[N][N], s[N][N];
int main() {
scanf("%d%d%d", &n, &m, &q);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
}
}
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][j];
}
}
while (q--) {
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);
}
return 0;
}

7、容易写错的地方#

(1)二维构造时循环边界写错#

for (int j = 1; j <= m; j++)

不要写成 j < m,否则最后一列不会被处理。

(2)查询循环变量写错#

二维前缀和通常有 q 次查询:

while (q--)

不要误写成 while (m--)。

(3)查询公式下标写混#

记住是:

右下 - 上方 - 左方 + 左上

总结#

前缀和适合“多次区间求和”。一维记住:

s[r] - s[l - 1]

二维记住:

大矩形 - 上面 - 左边 + 左上角

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

前缀和
https://blog.tjcheng.cn/posts/migrated/old-77/
作者
TengJinCheng
发布于
2025-10-02
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
TengJinCheng
Hello, I'm Teng.
公告
欢迎来到TengJinCheng工作铺!
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
分类
标签
站点统计
文章
157
分类
7
标签
114
总字数
109,939
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.13.4
文章许可
CC BY-NC-SA 4.0

文章目录