前缀和

一维前缀和

给定数组 a[N] : a[1],a[2],a[3]......a[n];

前缀和公式: S[i] = a[1]+a[2]+ ... +a[i]

a[l]+ ... +a[r] = S[r] - S[l - 1]

作用:求一个数组任意区间元素的和

注:前缀和数组下标往往从1开始,并令S[0] = 0. 方便计算例如 S[10] - S[0] = a[1] + a[2] + ... +a[10] 这样的前缀和。 

例题 

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

注:定义全局数组,若不进行初始化,数组中的各值为0; 定义局部数组,若不初始化,数组中的各值为随机值。 上述代码定义的是全局数组,所以S[0] = 0 可以省去。

 

二维前缀和

给定一个矩阵,求矩阵中子矩阵的和。

 

初始化:Sij = Si-1,j + Si,j-1 - Si-1,j-1 + aij 

求和: Sx2,y2 - Sx2,y1-1 - Sx1-1,y2 + Sx1-1,y1-1

例题 

#include <iostream>

using namespace std;

const int N = 10010;

int n,m,q;
int S[N][N];

int main()
{
    scanf("%d%d%d",&n,&m,&q);
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= m; j ++ )
        scanf("%d",&S[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] - S[i-1][j-1] + S[i][j]; //二维前缀和初始化
        
    while(q -- )
    {
        int x1,y1,x2,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        printf("%d\n",S[x2][y2] - S[x2][y1-1] - S[x1-1][y2] + S[x1-1][y1-1]);
        //二维子矩阵求和
    }
    return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值