前缀和数组 差分数组

前缀和

一维:通过空间换时间适用于需要频繁查询某一段区间和的场景。

一维数组:a_{1}a_{2}a_{3}...a_{n}

一维前缀和中的每一项:

c_{i}=\sum_{1}^{i}a_{i},该前缀和中的每一项也就是数组中对应的前 i 项和。

一维前缀和数组的构造:

在输入原数组时同步构造前缀和数组c_{i}=\sum_{1}^{i}a_{i}可以改写为c_{i}=c_{i-1}+a_{i}   

for(int i=1;i<=n;i++){
    scanf("%d",&arr[i]);
    crr[i]=crr[i-1]+arr[i];
  }

通常前缀和数组从下标为1开始c_{0}的值默认为0

一维区间和查询:

查询原数组区间为 [ l , r ] 的元素的和:c_{r}- c_{l-1}

二维:通过空间换时间适用于需要频繁查询某一个子矩阵中元素和的场景。

二维数组:

b_{00} b_{01} b_{02}b_{03}. ..b_{0m}

b_{10}b_{11}b_{12}b_{13}...b_{1m}

b_{20}b_{21}b_{22}b_{23}...b_{2m}

. . . . . . . . . . . . . . . 

b_{n0}b_{n1}b_{n2}b_{n3}...b_{nm}

二维前缀和中的每一项:

c_{xy}=\sum_{1}^{x}\sum_{1}^{y}c_{ij},该前缀和中的每一项也就是数组中以b_{11}b_{xy}这两个元素为对角线构成的矩形中元素和。

二维前缀和数组的构造:

也是在输入原数组时同步构造前缀和数组c_{xy}=\sum_{1}^{x}\sum_{1}^{y}c_{ij} 根据二维数组一行一行地读入顺序可以改写为c_{xy}=c_{(x-1)y}+\sum_{1}^{m}b_{xi}   ,运用这种类似于dp的想法就可以实现。

for(int i=1;i<=n;i++){
    int sum=0;
    for(int j=1;j<=m;j++){
      scanf("%d",drr[i][j]);
      sum+=drr[i][j];
      crr[i][j]=crr[i-1][j]+sum;
    }
  }

和一维类似:行和列的都从1开始

二维子矩阵元素和查询:

查询以b_{x_{1}y_{1}}b_{x_{2}y_{2}}为对角线构成的子矩阵中元素和:c_{x_{2}y_{2}}-c_{(x_{1}-1)y_{2}}-c_{x_{2}(y_{1}-1)}+c_{(x_{1}-1)(y_{1}-1)}

差分

一维:通过空间换时间适用于需要频繁进行区间数值的批量增减操作的场景。

一维数组:a_{1}a_{2}a_{3}...a_{n}

一维差分数组中的每一项:

d_{i}=a_{i}-a_{i-1}

一维差分数组的构造:

边输入原数组边构造

for(int i=1;i<=n;i++){
    scanf("%d",arr+i);
    diff[i]=arr[i]-arr[i-1];
  }

一维差分数组与原数组的推导关系: 由差分数组定义移项可得:a_{i}=d_{i}+a_{i-1}

一维差分数组实现区间批量增减:

让区间 [ l , r ] 上的元素加x:让d_{l} 加上x,让d_{r+1} 减去x 

这种区间批量增减操作是静态的无法一遍查询一边修改,需要统一在差分数组上修改完毕后再通过差分数组与原数组的关系还原回原数组,再实现查询。

二维:等待补充。。。。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值