二维前缀和(矩形割补法)——杨子曰算法

二维前缀和(矩形割补法)——杨子曰算法

今天曰一个很实用的技巧,二维前缀和
来,先问一个问题,如果我给出一个矩阵,让你求出任意一个子矩阵的和,你会怎么搞?
哦,简单简单,O(n^2)咔咔地暴力一下,欧了
要是真这么简单,我会问你吗?我们追求的是速度,做到O(n^2)读入后,O(1)搞定。


好的,你先要知道一个东西叫做前缀和,就是让你算出一个序列中子序列的和,
方法就是用f[i]存序列1~i的和,那么询问x,y,答案就是f[y]-f[x-1]
如果你已经知道了这个,我们就来讨论二维的情况吧
杨子曰:题目的思想是可以转移的,So在二维情况是我们同样用一个数组f[i][j]表示a[1,1]为左上角a[i][j]为左下角的子矩阵的和,如图
在这里插入图片描述
f[3][4]就是表示绿色部分的和
知道了这个以后,我们就开始来看一看一个任意的以(x1,y1)为左上角,(x2,y2)为右下角的子矩阵怎么求:
这里写图片描述
首先这个矩阵的和肯定包括在f[x2][y2]中,但是多了一些东西,所以我们要把蓝的,黄的,绿的部分减去,首先看如何减去蓝的,用最粗暴的方法,直接减掉f[x1-1,y2],好现在只要减掉一个绿色部分就行了,依然用简单粗暴的办法,减掉f[x2][y1-1]
噢,有人举起了手,可是黄色部分被减了两遍呀,不要紧张,加回去就得了呗,
So,杨子曰:子矩阵的和就等于f[x2][y2]-f[x1-1][y2]-f[x2][y1-1]+f[x1-1][y1-1]
这样我们,就做到了O(1)取到子矩阵的和
OK,完事

呵呵,代码才打了一个开头就打不下去了对吧,f[i][j]怎么预处理啊啊啊啊!
其实也是比较简单的,look at the图:
这里写图片描述
你要算出黄绿蓝,三个部分的和,你要知道,当你再算f[i][j]的时候已经算好了f[i-1][j],f[i][j-1],f[i-1][j-1]
所以先用f[i-1][j]+f[i][j-1],NO,黄色部分被加了两边呀,额,一样的套路,减掉不就欧了吗,
So,杨子曰:f[i][j]=f[i-1][j]+f[i][j-1]-f[i][j]
这回是真的
OK,完事
于TJQ高层小区

未经作者允许,严禁转载:https://blog.csdn.net/henryyang2018/article/details/79734675

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值