一:定义
对于一个数组a来说,假定它的前缀和数组是s,那么s[i]表示a数组中前i项的和
二:作用
可以在O(1)的时间中求出某一个区间内数的和,在今后的学习中,是一种很重要的预处理方法
三:一维前缀和
一维数组的前缀和就不多说了,可以参考csdn上的其他博客或OI Wiki理解
那么一维前缀和的代码就是
#include<bits/stdc++.h>
using namespace std;
int a[114514];
int sum[114514];//a的前缀和数组
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)sum[i] = sum[i-1]+a[i];
return 0;
}
那我们现在有了a的前缀和数组sum,有什么用呢?
多想想就能想到
我们可以用来求某一个区间内数的和
那怎么求呢?
因为sum存的是a数组中前i项的和,所以如果我们要求一个区间内的和,就可以
int s;//结果
int x;//左节点
int y;//右节点
s = sum[y]-sum[x];
cout<<s;
因为sum[y] == sum[x-1]+(a[x]+a[x+1]+a[x+2]+...+a[y-2]+a[y-1]+a[y])
所以a[x]到a[y]的和就等于sum[y]-sum[x-1]
这样我们就可以很快速的求出一个区间内的和了
四:二维前缀和
二维前缀和与一维前缀和差别不大
二维的前缀和sum[i][j]表示从a[1][1](或者其他其点,这里因个人码分用a[1]a[1])到a[i][j]内这一个矩阵的和
是不是看起来很像( •̀ ω •́ )✧
但又有蒟蒻要问了
那sum又怎么写呢?
因为是从a[1][1]到a[i][j]的和
所以sum[i][j]就等与sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j]
这时有的小蒟蒻又说了:"这么长的代码,看着就让人头晕"
那就让我们来拆解一下这段代码
因为我们要求sum[i][j],所以把他拆成俩部分,一部分时a[i][j]
另一部分就是除a[i][j]以外的部分
那么另外的部分就是sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]
因为sum[i-1][j]+sum[i][j-1]包括了剩下的部分,但还有重叠的部分sum[i-1][j-1],所以减去
那么二维前缀和的代码就是
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[114][514];
int sum[114][514];
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
sum[i][j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
return 0;
}
我们有了这个就可以在O(1)求出任意一个矩阵的和
代码如下(思路类比求sum[i][j])
int i1,j1;//左上角坐标
int i2,j2;//右上角坐标
int s;//结果
cin>>i1>>j1>>i2>>j2;
s = sum[i2][j2]-sum[i2][j1-1]-sum[i1-1][j2]+sum[i1-1][j1-1];
cout<<s;
五:推荐
如果这篇博客对您有帮助的话,别忘了点赞收藏加关注支持一下吖~(超大声)