这是C++算法基础-基础算法专栏的第十二篇文章,专栏详情请见此处。
ps:上个周去旅游,忘记发文了,在这里向大家说声抱歉,预计将会在周五再发一篇文章补偿─=≡Σ(((つ•̀ω•́)つ
引入
上次我们学习了在一维数组上的一维前缀和方法,而在二维数组上的二维前缀和也有和一维前缀和一样的优异功能。
下面我们就来讲二维前缀和的实现。
二维前缀和与一维前缀和的定义是大致相同的,如果想了解具体内容,可以移步至我的这篇博客:一维前缀和的实现。
在这里就不再详细讲解,只讲解主体过程qwq
过程
二维前缀和较复杂,它是基于容斥原理实现的。
表示
对于原数组,二维前缀和额外开辟了一个数组,中储存了格子左上部分所有元素的和,也就是说,。
赋值
赋值操作一般在输入数组时同时进行,那么如何推出递推公式呢?
首先,图一展示了起始状态,然后,我们将之前的(图二)与(图三)计入总和,但这时我们发现格子左上部分所有元素的和的部分多加了一次,所以将减去(图四),最后,将计入总和(图五)。
所以,递推公式就是。
求区间和
当我们想得到数组以为左上角,位右下角的子矩阵的和,应该怎么去做呢?
首先,图一展示了起始状态,然后,我们将计入总和(图二),由于我们不想将之前的(图三)与(图四)计入总合,所以将其减去,但这时我们发现格子左上部分所有元素的和的部分多减了一次,所以将计入总合(图五)。
得出结论:以为左上角,为右下角的子矩阵的和的计算公式为。
代码
下面给出二维前缀和代码:
表示:s[i][j]=第i行j列格子左上部分所有元素的和
赋值:s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]+a[i-1][j-1]
求和:以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和的计算公式为:s[x2,y2]-s[x1-1,y2]-s[x2,y1-1]+s[x1-1,y1-1]
上一篇-一维前缀和的实现 C++算法基础专栏文章 下一篇-一维差分的实现
每周六更新一篇文章,内容一般是自己总结的经验或是在其他网站上整理的优质内容
点个赞,关注一下呗~