子矩阵的和(二维前缀和)

这篇具有很好参考价值的文章主要介绍了子矩阵的和(二维前缀和)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、算法描述

上一篇文章介绍了一维前缀和,也就是一个数组的前n项和,这篇文章来介绍一下什么是二维前缀和。

含义

  • 一维的是前n项的和,那么二维的情况下,表示的则是与左上角形成的矩形和。

怎么求

  • 一维的递推关系式是s[i] = s[i - 1] + a[i];,我们根据含义来思考二维的递推关系式,读者可以在草稿纸上画一个矩形来更好的理解。

  • \(s[i][j]\) 表示的是 \(i, j\) 这个位置与左上角形成的矩形和,\(s[i - 1][j]\) 表示的是比 \(s[i][j]\) 少一行的矩形和, \(s[i][j - 1]\) 表示的是比 \(s[i][j]\) 少一列的矩形和。

  • \(s[i - 1][j] + s[i][j - 1]\) 得到的就是 \(s[i][j]\) ,但是少了一个 \(a[i][j]\) ,同时多了一个 \(i - 1, j - 1\) 与左上角形成的矩形和,即 \(s[i - 1][j - 1]\)

  • 综上可以得到求得 \(s[i][j]\) 的递推关系式为:s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];,读者应在草稿纸上自己推理,不要纯靠记忆。

怎么用

  • 一维前缀和的用法在 \(O(1)\) 的时间复杂度内求得 \([l, r]\) 的区间和,那么二维前缀和则是在 \(O(1)\)的时间复杂度内求得 \([x1, y1]\)\([x2, y2]\)这个区域的矩形和。

  • 显然我们要用 \(s[i][j]\) 这块大面积来减去其他的面积,那么需要减去哪些部分呢?大家自行在草稿纸上推演,计算如下:s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];,根据含义来思考如何推算。

二、题目描述

输入一个 \(n\)\(m\) 列的整数矩阵,再输入 \(q\) 个询问,每个询问包含四个整数 \(x1, y1, x2, y2\),表示一个子矩阵的左上角坐标和右下角坐标。

对于每个询问输出子矩阵中所有数的和。

输入格式

第一行包含三个整数 \(n, m, q\)

接下来 \(n\) 行,每行包含 \(m\) 个整数,表示整数矩阵。

接下来 \(q\) 行,每行包含四个整数 \(x1, y1, x2, y2\),表示一组询问。

输出格式

\(q\) 行,每行输出一个询问的结果。

数据范围

\(1≤n,m≤1000,\)
\(1≤q≤200000,\)
\(1≤x1≤x2≤n,\)
\(1≤y1≤y2≤m,\)
\(1000≤矩阵内元素的值≤1000\)文章来源地址https://www.toymoban.com/news/detail-711383.html

输入样例:

3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4 

输出样例:

17
27
21 

三、题目来源

AcWing算法基础课-796.子矩阵的和

四、源代码

#include <iostream>

using namespace std;

const int N = 1010;

int n, m, q;
int a[N][N], s[N][N];

int main()
{
    cin >> n >> m >> q;
    
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            cin >> a[i][j];
        
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + a[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;
}

到了这里,关于子矩阵的和(二维前缀和)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 二维前缀和公式 AcWing 796. 子矩阵的和

    记住两个公式就行 不知道算难还是算简单,公式就是代码里面写的那样,完完全全公式,没有任何其他东西

    2024年02月19日
    浏览(46)
  • 前缀和例题:子矩阵的和AcWing796-Java版

    //前缀和模板提,在读入数据的时候就可以先算好前缀和的大小 // 计算前缀的时候用 :g[i][j] = g[i][j-1] + g[i-1][j] - g[i-1][j-1] + Integer.parseInt(init[j-1]); // 计算结果的时候用 :g[x2][y2] - g[x1 - 1][y2]- g[x2][y1-1]   + g[x1 -1][y1 - 1] + \\\"n\\\" //一些重复加的地方都需要减掉,如计算前缀和的时候 g[i-1

    2024年02月02日
    浏览(44)
  • 前缀和--二维矩阵的前缀和

    原题链接 输入一个 n 行 m 列的整数矩阵,再输入 q 个询问,每个询问包含四个整数 x1,y1,x2,y2 ,表示一个子矩阵的左上角坐标和右下角坐标。 对于每个询问输出子矩阵中所有数的和。 输入格式 第一行包含三个整数 n,m,q 。 接下来 n 行,每行包含 m 个整数,表示整数矩阵。

    2024年01月16日
    浏览(43)
  • C++ 二维差分 二维前缀和逆运算 差分矩阵

    输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c ,其中 (x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将选中的子矩阵中的每个元素的值加上 c 。 请你将进行完所有操作后的矩阵输出。 输入格式 第一行包含整数

    2024年02月21日
    浏览(55)
  • 【力扣】304. 二维区域和检索 - 矩阵不可变 <二维前缀和>

    给定一个二维矩阵 matrix ,以下类型的多个请求: 计算其子矩形范围内元素的总和,该子矩阵的 左上角 为 (row1, col1) ,右下角 为 (row2, col2) 。 实现 NumMatrix 类: NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进行初始化 int sumRegion(int row1, int col1, int row2, int col2) 返回 左上角 (row1, co

    2024年02月10日
    浏览(39)
  • lintcode 1840 · 矩阵还原【中等 vip 二维前缀和数组】

    https://www.lintcode.com/problem/1840

    2024年02月04日
    浏览(43)
  • 《剑指 Offer》专项突破版 - 面试题 13 : 二维子矩阵的数字之和(C++ 实现)- 二维前缀和

    题目链接 :LCR 013. 二维区域和检索 - 矩阵不可变 - 力扣(LeetCode) 题目 : 输入一个二维矩阵,如何计算给定左上角坐标和右下角坐标的子矩阵的数字之和?对于同一个二维矩阵,计算子矩阵的数字之和的函数可能由于输入不同的坐标而反复调用多次。 例如,对于下图中的二

    2024年01月18日
    浏览(40)
  • 一、二维前缀和算法

    一维前缀和: 二维前缀和: 给你一个整数数组 nums ,请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中

    2024年02月16日
    浏览(35)
  • 前缀和算法【一维、二维】

    首先这种算法适合于求 从 x 到 y 的和 。 一维代码十分简单,我们只需要每个都记录前面所有的和即可,注意细节 下标从1开始 这里我们就看两种情况:一种是 开始时 ,一种是 执行中 在开始时,因为我们是从1开始,a[0] = 0,所以第一个就是temp; 在执行过程中,因为前一个是

    2023年04月18日
    浏览(31)
  • 每周一算法:二维前缀和

    对一个序列预处理得到前缀和数组,可以在 O ( 1 ) O(1) O ( 1 ) 的时间复杂度计算序列中任意区间的元素之和,这是前缀和算法的作用。而二维前缀和是用来优化处理子矩阵的和。 例如,对于矩阵 A = [ 1 4 5 2 9 5 2 1 6 9 8 3 4 2 1 6 ] A=left[ begin{matrix}1 4 5 2\\\\ 9 5 2 1 \\\\ 6 9 8 3 \\\\ 4 2 1 6en

    2024年02月06日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包