AcWing 一维前缀和与二维前缀和
一、一维前缀和
场景模拟:
老师让 班长糖豆 帮着计算一下全班同学语文考试的总分,老师负责读每个同学的分数,糖豆负责计算。
老师:“第一名,张三 分”, 糖豆记录如下:分
老师:“第二名,李四 分”, 糖豆 擦去 ,修改为:分
老师:“第三名,王五 分”, 糖豆 擦去 ,修改为:分
...
老师:“第四十五名,赵九 分”, 糖豆 擦去 ,修改为:分
完事了,糖豆汇报总分:“分!任务结束!”
老师想了一想,问了一句:“那前十名共多少分?”
糖豆有点懵,因为把前十位的结果已经擦去啦!只能让老师从第一名开始到第十名再读一次。_
老师又想问:"那前二十名共多少分?"
糖豆彻底懵了,只能让老师从第一名开始到第二十名再读一次。_
老师也疯了!!!
看来这个办法不太行,老师的需求总变化!
那有什么办法呢??糖豆会有办法的:
记录前个同学的分数总和!不擦!
来吧,老师,你说你想要啥?
我想要前名的分数总和!没问题,我记的就是这个,给你!
我想要至名的分数总和!啊???还想这么要?怎么办呢?
我们用数学的公式来描述一下,这样方便说明:
代表号同学分数,代表号同学及他以前的所有同学的分数总和。
那么有下面的关系式:
①
②
将①式代入②式,得到
③
如果记录了这个,就能回答好多的问题:
1、第名同学的分数是多少?
答: ,为啥呢?因为③式的变形
2、第名到第名同学的分数和是多少?
答: 为啥呢?因为前缀和定义就是从1
到i
的数据和嘛。
3、第名到第名同学的分数和是多少?
答:
为啥呢?
其实我们想求的是:
我们使用来构建上面的式子:
①
②
将①式代入②式,就是
移项得到:
注意:
前缀和一般从数下标开始,这是因为它的定义是,如果从开始,数组下标就会出现负数,这样还需一堆判断,麻烦,所以,一般为了代码简单,我们都把,通常在全局变量区域里定义数组,这样连也省略了,其实也是定义在全局变量区域的,所以,这样操作代码就简单了。
1. 使用场景
给定一个原始数组,后面需要多次查询某一个的数值和,比如 ,个数字,需要问次,每次问从x
到y
的位置,相加的和是几。
如果按普通想法,就是每问一次就计算一次,不利用以前的结果。这样假设每次的l
到r
的距离是m
,很显然,共需要m*N
次操作,如果使用了前缀和的预处理,计算一次前缀和,就是N
次运算,得到一个结果数组s[N]
,以后每次查询都是 ,就是一次运算,快了很多。
. 前缀和
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int q[N];
int s[N];
//一维前缀和
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> q[i];
s[i] = s[i - 1] + q[i];
}
while (m--) {
int l, r;
cin >> l >> r;
printf("%d\n", s[r] - s[l - 1]);
}
return 0;
}
. 子矩阵的和
什么是二维前缀和?
a[N][M]
假设为原数组,s[N][M]
为二维前缀和数组,s[i][j]
的意义是:原数组前i
行,前j
列的数组元素值的和。
说白了,就是1->i
行,1->j
列的所有元素值的和,就是左上角的格子内容和:
本质上和一维前缀和是一个意思,一维是第1
个元素到第n
个元素的累加和,二维是从左上角到(i,j)
的累加和。
1、公式的推导
观察上面4个式子,我们想要计算,还不想用笨办法,一个个用来累加出来,就可以利用已经算出来的结果值进行运算获得!
抽象一下,就是:(如果感觉看代数式子不好理解,就用上面图理解就行啦!)
2、计算子区域的前缀和
3、C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N][N];
int s[N][N];
int main() {
int n, m, q;
cin >> n >> m >> q;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
s[i][j] = s[i - 1][j] + s[i][j - 1] + a[i][j] - s[i - 1][j - 1];
}
while (q--) {
int x1, y1, x2, y2;
cin >> 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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2015-07-01 数据库技术进化路线
2013-07-01 CentOS 6.4安装本地yum源,并安装X Window System