news 2026/3/26 21:33:23

前缀和(一维, 二维)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
前缀和(一维, 二维)

一.为什么我们要学前缀和

这里我想通过一道例题来解释为什么我们需要学前缀和?学前缀和有什么好处?

P8218 【深进1.例1】求区间和

题目描述

给定由nnn个正整数组成的序列a1,a2,⋯ ,ana_1, a_2, \cdots, a_na1,a2,,anmmm个区间[li,ri][l_i,r_i][li,ri],分别求这
mmm个区间的区间和。

输入格式

第一行包含一个正整数nnn,表示序列的长度。

第二行包含nnn个正整数a1,a2,⋯ ,ana_1,a_2, \cdots ,a_na1,a2,,an

第三行包含一个正整数mmm,表示区间的数量。

接下来mmm行,每行包含两个正整数li,ril_i,r_ili,ri,满足1≤li≤ri≤n1\le l_i\le r_i\le n1lirin

输出格式

mmm行,其中第iii行包含一个正整数,表示第iii组答案的询问。

输入输出样例 #1

输入 #1

4 4 3 2 1 2 1 4 2 3

输出 #1

10 5

说明/提示

样例解释

111到第444个数加起来和为101010。第222个数到第333个数加起来和为555

数据范围

对于50%50 \%50%的数据:n,m≤1000n,m\le 1000n,m1000

对于100%100 \%100%的数据:1≤n,m≤1051 \le n, m\le 10^51n,m1051≤ai≤1041 \le a_i\le 10^41ai104

对于这道题,如果我们根据输入临时求区间[l, r]的和,大概率会写出这样的代码

for(inti=1;i<=m;i++){cin>>l>>r;sum=0;for(intj=l;j<=r;j++){sum+=a[j];}}

显然,这样的算法的时间复杂度是O(mn)O(mn)O(mn), 肯定会超时,这时我就想引出前缀和,通过此法,可以极大压缩时间复杂度,达到以空间换时间的效果

二.前缀和原理

1.一维前缀和


如图所示,易得

prefixSum[i]=A[1]+A[2]+⋯+A[i−1]+A[i]prefixSum[i] = A[1] + A[2] + \dots + A[i - 1] + A[i]prefixSum[i]=A[1]+A[2]++A[i1]+A[i]

依据此公式我们可以非常轻松的求出[l,r][l, r][l,r]上数组AAA元素的和

即,suml,r=prefixSum[r]−prefixSum[l−1]sum_{l, r} = prefixSum[r] - prefixSum[l - 1]suml,r=prefixSum[r]prefixSum[l1]

和我们高中所学的数列是一个原理

在我们掌握了这个知识点之后, 只需要提前准备好prefixSumprefixSumprefixSum数组,上面那道题就可以这样求解了

for(inti=1;i<=m;i++){cin>>l>>r;sum=prefixSum[r]-prefixSum[l-1];}

此外前缀和还有一个递推公式可以帮助我们求prefixSumprefixSumprefixSum数组

prefixSum[i]=prefixSum[i−1]+A[i]prefixSum[i] = prefixSum[i - 1] + A[i]prefixSum[i]=prefixSum[i1]+A[i]

代码示例

for(inti=1;i<=n;i++){cin>>A[i];prefixSum[i]=prefixSum[i-1]+A[i];}

2.二维前缀和

在介绍完了以上比较简单的一维前缀和之后, 我还想再解释一下二维前缀和, 如果遇到给定矩形区域的范围, 我们是否也能用O(1)O(1)O(1)的时间复杂度求出区域内的数值之和呢? 答案当然是肯定的


同样的道理
prefixSum[i][j]=A[1][1]+A[1][2]+⋯+A[1][j−1]+A[1][j]+A[2][1]+A[2][2]+⋯+A[2][j−1]+A[2][j]+…+A[i][1]+A[i][2]+⋯+A[i][j−1]+A[i][j] \begin{aligned} prefixSum[i][j] = &A[1][1] + A[1][2] + \dots + A[1][j - 1] + A[1][j] +\\ &A[2][1] + A[2][2] + \dots + A[2][j - 1] + A[2][j] +\\ & \dots\\ &+ A[i][1] + A[i][2] + \dots + A[i][j - 1] + A[i][j] \end{aligned}prefixSum[i][j]=A[1][1]+A[1][2]++A[1][j1]+A[1][j]+A[2][1]+A[2][2]++A[2][j1]+A[2][j]++A[i][1]+A[i][2]++A[i][j1]+A[i][j]
由此我们可以得出
(x1,y1)(x1, y1)(x1,y1)为左上角,(x2,y2)(x2, y2)(x2,y2)为右下角的矩形区域内的元素和公式

sum(x1,y1),(x2,y2)=prefixSum[x2][y2]−prefixSum[x2][y1−1]−prefixSum[x1−1][y2]+prefixSum[x1−1][y1−1] \begin{aligned} sum_{(x1, y1), (x2, y2)} =& prefixSum[x2][y2] - prefixSum[x2][y1 - 1] -\\ &prefixSum[x1 - 1][y2] + prefixSum[x1 - 1][y1 - 1] \end{aligned}sum(x1,y1),(x2,y2)=prefixSum[x2][y2]prefixSum[x2][y11]prefixSum[x11][y2]+prefixSum[x11][y11]

例如, 我们可以轻松算出

sum(2,2),(3,4)=7+7+3+1+10+1=29sum_{(2, 2), (3, 4)} = 7 + 7 + 3 + 1 + 10 + 1 = 29sum(2,2),(3,4)=7+7+3+1+10+1=29


同样也有
sum(2,2),(3,4)=prefixSum[3][4]−prefixSum[3][1]−prefixSum[1][4]+prefixSum[1][1]=52−9−16+2=29 \begin{aligned} sum_{(2, 2), (3, 4)} =& prefixSum[3][4] - prefixSum[3][1] -\\ &prefixSum[1][4] + prefixSum[1][1] \\ =&52 - 9 - 16 + 2 \\ =&29 \end{aligned}sum(2,2),(3,4)===prefixSum[3][4]prefixSum[3][1]prefixSum[1][4]+prefixSum[1][1]52916+229

其实原理非常简单,利用容斥定理,我们要求出一个矩形区域内的元素和,就用
“一个大的,减去两边两个小的,然后多减的一块再加上就行”, 这点结合图示非常容易理解

这里还有一个二维前缀和的递推公式可以辅助我们求prefixSumprefixSumprefixSum数组

prefixSum[i][j]=prefixSum[i][j−1]+prefixSum[i−1][j]−prefixSum[i−1][j−1]+A[i][j]prefixSum[i][j] = prefixSum[i][j - 1] + prefixSum[i - 1][j] - prefixSum[i - 1][j - 1] + A[i][j]prefixSum[i][j]=prefixSum[i][j1]+prefixSum[i1][j]prefixSum[i1][j1]+A[i][j]

代码如下

for(inti=1;i<=n;i++){for(intj=1;j<=m;j++){cin>>A[i][j];prefixSum[i][j]=prefixSum[i-1][j]+prefixSum[i][j-1]-prefixSum[i-1][j-1]+A[i][j];}}

三.总结

不论是一维前缀和还是二维前缀和,都是一种对数据的预处理,然后利用空间换时间的策略,如果这块掌握好了,可以极大的减少时间复杂度,提升代码的通过率

后续如果有空,我会在下面贴一些关于本节,且比较适合新手练手的题目…

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/26 16:36:20

CI/CD流水线集成:从GitHub提交到生产环境自动部署

CI/CD流水线集成&#xff1a;从GitHub提交到生产环境自动部署 在AI语音合成系统日益普及的今天&#xff0c;一个新功能从开发完成到上线服务往往需要经历代码提交、依赖安装、服务重启、健康检查等多个步骤。对于像GLM-TTS这样依赖特定Python环境和GPU资源的模型服务而言&#…

作者头像 李华
网站建设 2026/3/20 6:58:04

桥式整流电路启动冲击电流:整流二极管保护策略

桥式整流电路的“上电惊魂”&#xff1a;如何驯服启动冲击电流&#xff0c;守护整流二极管&#xff1f;你有没有遇到过这样的情况&#xff1f;一台电源设备在冷启动时“啪”地一声&#xff0c;保险丝烧了&#xff1b;或者频繁启停后&#xff0c;整流桥莫名其妙发热、甚至炸裂&a…

作者头像 李华
网站建设 2026/3/26 21:24:25

前后端分离图书个性化推荐系统系统|SpringBoot+Vue+MyBatis+MySQL完整源码+部署教程

摘要 随着互联网技术的快速发展和数字化阅读的普及&#xff0c;图书推荐系统在提升用户体验和满足个性化需求方面发挥着重要作用。传统的图书推荐系统往往存在推荐精度不高、响应速度慢、用户体验不佳等问题&#xff0c;难以满足现代读者的多样化需求。个性化推荐系统通过分析用…

作者头像 李华
网站建设 2026/3/21 23:32:24

翻译专业留学信息差避坑:衔接时代的留学与求职

翻译专业留学的核心痛点&#xff0c;从来都藏在“信息差”里——不少学生盲目追名校、堆绩点&#xff0c;却忽略了行业正在发生的深层变革&#xff0c;等留学归来才发现&#xff0c;自己的技能早已跟不上市场需求&#xff0c;陷入“空有留学背景却无对口岗位”的困境。如今翻译…

作者头像 李华
网站建设 2026/3/23 9:43:19

⚡_实时系统性能优化:从毫秒到微秒的突破[20260104165159]

作为一名专注于实时系统性能优化的工程师&#xff0c;我在过去的项目中积累了丰富的低延迟优化经验。实时系统对性能的要求极其严格&#xff0c;任何微小的延迟都可能影响系统的正确性和用户体验。今天我要分享的是在实时系统中实现从毫秒到微秒级性能突破的实战经验。 &#…

作者头像 李华
网站建设 2026/3/23 11:36:52

语音合成中的语气助词添加:‘啊’、‘呢’、‘吧’自然融入

语音合成中的语气助词添加&#xff1a;‘啊’、‘呢’、‘吧’自然融入 在智能客服自动应答、虚拟主播直播带货、有声书朗读等场景中&#xff0c;我们常常会发现一个微妙但刺耳的问题&#xff1a;机器说话“太正经”了。比如一句本该轻松随意的“要不要一起去啊&#xff1f;”…

作者头像 李华