题解 | #【模板】二维前缀和#

【模板】二维前缀和

http://www.nowcoder.com/practice/99eb8040d116414ea3296467ce81cbbc

描述

给定一个nmn*m的矩阵,qq次询问,每次询问(x1,y1)(x_1,y_1)为左上角,(x2,y2)(x_2,y_2)为右下角的子矩阵的和

思路

  • 二维前缀和的模板题,设矩阵aa中,左上角为(1,1)(1,1),右下角为(x,y)(x,y)的矩阵和为sum[x][y]sum[x][y],根据容斥原理转移公式为sum[x][y]=sum[x1][y]+sum[x][y1]sum[x1][y1]+a[x][y]sum[x][y]=sum[x-1][y]+sum[x][y-1]-sum[x-1][y-1]+a[x][y]

  • 对于询问(x1,y1)(x_1,y_1)为左上角,(x2,y2)(x_2,y_2)为右下角的子矩阵的和,根据容斥原理,答案为为ans=sum[x2][y2]sum[x11][y2]sum[x2][y11]+sum[x11][y11]ans=sum[x_2][y_2]-sum[x_1-1][y2]-sum[x2][y_1-1]+sum[x_1-1][y_1-1]

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e3+5;
ll sum[MAXN][MAXN];
int main()
{
    int n,m,q;
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%lld",&sum[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    while(q--)
    {
        int x1,x2,y1,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        ll ans=sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];
        printf("%lld\n",ans);
    }
}

时间复杂度O(nm+q)O(nm+q),空间复杂度O(nm)O(nm)

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务