【数组】 前缀和补充

【数组】 前缀和补充

考虑到昨天写的前缀和博客有所欠缺,所以写这篇博客作为上一篇博客的补充。

二维数组的前缀和

首先,我们从先前提到过的一维数组的前缀和谈起。

而一维数组的前缀“和”的作用便是对以区间为单位进行操作,
我们基于这个概念,引入二维数组的前缀和。

那么二维数组的前缀和,也就是矩阵中一个子矩阵的元素和。
其中右下角a[4][5]的前缀和就是矩阵所有元素的和。
同样的,二维数组的前缀“和”对以二维区间,也就是子矩阵为单位进行操作。

求二维数组的前缀和也很简单,只需要明确概念后画图进行模拟即可。
假设,我们有要对二维数组中的某一个元素求前缀和,类比一维数组的递推表达式s[n] = s[n-1] + a[n],我们同样可以写出一个递推表达式。

如图,我们要求红色区域,即元素(i,j)的前缀和,类比一维求法,我们同样根据先前求出来的前缀和加上(i,j)元素求前缀和。

则 为绿色部分 + 蓝色部分 - 混色部分 + (i,j)值
假设前缀和数组为s[i][j] , 原数组为a[i][j];

我们得到关系式:s[i][j] = s[i-1][j](蓝色) + s[i][j-1](绿色) -s[i-1][j-1](混色) + a[i][j];

借助几何意义,我们同样可以推出子矩阵的和的公式。

给出四个整数 x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标

s[x2][y2] - s[x2][y1-1]-s[x1-1][y2] + s[x1-1][y1-1]

以下给出一道例题作为参考。

题目出自acwing,侵删。
以下为代码

{
    #include <iostream>
    #define N 1010
    using namespace std;
    int f[N][N];
    int s[N][N];
    int main()
    {
        int n,m,q;
        cin >> n >> m >> q;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++){
                cin >> f[i][j];
                s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + f[i][j];
            }
        while(q--)
        {
            int x1,y1,x2,y2;
            cin >> x1 >> y1 >> x2 >> y2;
            cout << s[x2][y2] - s[x2][y1-1]-s[x1-1][y2] + s[x1-1][y1-1] << endl;//通过对前缀和进行运算求子矩阵的和;
        }
        return 0;
    }
}
posted @ 2023-01-15 23:52  瞻鹤  阅读(60)  评论(3编辑  收藏  举报