前缀和与差分、二维前缀和

本文探讨了前缀和与差分数组在解决查询区间和的问题上的高效算法。通过动态规划计算前缀和,以及利用差分数组快速更新和查询区间的变化,展示了如何在O(n+m)时间内处理n个数和m个操作。重点介绍了如何处理指令对差分数组的影响,以及二维前缀和在矩阵查询中的应用实例。
摘要由CSDN通过智能技术生成

前缀和

题目:有 n 个数,并且有 m 次操作,每一次操作要求查询第 x 个数到第 y 个数的和。

前缀和是一种动态规划的思想,假如有数组 a[i] 。

定义 sum[i] 表示从 1 到 a[i] 的和。状态转移方程则是: sum[i] = sum[i-1] + a[i] ;  其中 sum[1] = a[1] ; 

这样可以在O(n)的时间计算出整个数组的前缀和。

查询 a[x...y] = sum[y] - sum[x-1] ;

 

差分

差分:我们定义 f[i] 表示 a[i] 与 a[i-1] 的差, 则f[i] = a[i] - a[i-1] ; 其中 f[1] = a[1];
差分数组有这样一个性质:对差分数组 f 做前缀和即是原始数组 a 。

例如:                数组 a 为 : 5  3  9  2   6
                    差分数组 f 为:   5 -2  6 -7  4
对差分数组做前缀和 sum:    5  3  9  2  6 

这个性质非常重要,说明差分数组 f  可以通过计算前缀和 得出原始数组 a 。

 

前缀和与差分

题目:有大小为 n 的数组,现在有 m 个指令,第 i 个指令要求将第 xi 个数到第 yi 个数的每个数加上 k,最后求所有数的值。

指令要求将 xi 个数到 yi 个数都加上k,如果我们立即执行这一指令,无疑是暴力算法,而题目要求的是 i 条指令都结束后再查询值,所以我们没必要立即执行指令。

有了差分的知识,我们再来看题目中的指令,指令将一段连续的区间 a[x...y] 都增加 k,这对于差分数组有什么影响呢?
很明显只会影响 f[x] 和 f[y+1] ,中间段的数据的差还是不变的。

所以对于指令a[x..y]都增加 k ,我们可以把其影响记录到差分数组上,也就是 f[x]+=k; f[y+1]-=k;
最后再做一遍前缀和即可得到最终的数据。

时间复杂度是O(n+m)。

题目:https://ac.nowcoder.com/acm/contest/10322/B

 

二维前缀和

给定一个 n×m 的矩阵 t ,有 T 次询问,每次会给出四个数 a,b,c,d,求以点 (a,b) 为左上角,点 (c,d) 为右下角的矩形的和。

定义 sum[i][j] 表示以 t[1][1] 为左上角,以 t[i][j] 为右下角的矩形的和。

状态转移方程:sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + t[i][j] ;

查询以点 (a,b) 为左上角,点 (c,d) 为右下角的矩形的和: x = sum[c][d] - sum[a-1][d] - sum[c][b-1] + sum[a-1][b-1];

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值