前缀和详解

 一:定义

对于一个数组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;

五:推荐

如果这篇博客对您有帮助的话,别忘了点赞收藏加关注支持一下吖~(超大声)

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值