【基础算法笔记】前缀和

 在acwing上学习算法的一点简短的总结


一维前缀和

分析:可以类比一下高中时候学的 S(n) - S(m-1),求的就是数列a的m项到第n项的和。迁移到代码中也是一样的思路。

核心:s[i] = s[i - 1] + a[i] (不断累加a数组里的值)

#include <iostream>

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;
}

二维前缀和

我们把这个整数矩阵用一个方格图来表示,这样更容易理解。

然后就是要解决怎么求出子矩阵所有数的和了。由于上升了一个维度,前缀和的表达式也就要对应多一个维度。原本一维只用考虑一个方向,那么放在在一个二维平面图中我们可以分为横纵两个方向来看。如下图s [ 2 ][ 3 ] = s[ 1 ][ 3 ] + s[ 2 ][ 2 ] + a[ 2 ][ 3 ] - s[ 1 ][ 1 ]

推广出来就是 s[i][j] = s[i-1][j] + s[i][j-1] + a[i][j] - s[i-1][j-1]

接下来继续推广得出子矩阵和的公式为s[x2,y2]−s[x1−1,y2]−s[x2,y1−1]+s[x1−1,y1−1]

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 1010;
int a[N][N], 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];
    
    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] + a[i][j] - s[i-1][j-1];
            
    while(q--)
    {
        int x1,x2,y1,y2;
        cin>>x1>>y1>>x2>>y2;
        cout<<s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]<<endl;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值