798.差分矩阵 做题笔记

本题利用的思想和一维差分/前缀和类似。

首先构造原数组的差分数组a:a[i][j] = s[i][j] - s[i - 1][j] - s[i][j - 1] + s[i - 1][j - 1];

然后通过修改差分数组达到改变前缀和数组的目的。

始终要记得,s数组是a数组的前缀和数组,比如对a数组的a[i][j]的修改,会影响到s数组中从s[i][j]及往后的每一个数。

a[x1][ y1 ] +=c ; 让整个s数组中蓝色矩形面积的元素都加上了c。
a[x1,][y2+1]-=c ; 让整个s数组中绿色矩形面积的元素再减去c,使其内元素不发生改变。
a[x2+1][y1]- =c ; 让整个s数组中紫色矩形面积的元素再减去c,使其内元素不发生改变。
a[x2+1][y2+1]+=c; 让整个s数组中红色矩形面积的元素再加上c,红色内的相当于被减了两次,再加上一次c,才能使其恢复。

修改a数组后,重新循环构造新的前缀和数组,此时这个前缀和数组s就是我们想要的答案。

#include<iostream>
using namespace std;
const int N = 1010;
int n, m, q;
int a[N][N], s[N][N];

int main()
{
    scanf("%d%d%d",&n,&m,&q);
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            scanf("%d", &s[i][j]);

    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            a[i][j] = s[i][j] - s[i - 1][j] - s[i][j - 1] + s[i - 1][j - 1];//构造差分数组

    while (q -- )
    {
        int x1, y1, x2, y2, c;
        scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &c);
        a[x1][y1] += c;//通过改变差分数组来修改前缀和数组
        a[x1][y2 + 1] -= c;
        a[x2 + 1][y1] -= c;
        a[x2 + 1][y2 + 1] += c;
    }

    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            s[i][j] = a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];//重新构造前缀和数组

    for (int i = 1; i <= n; i ++ )
    {
        for (int j = 1; j <= m; j ++ ) printf("%d ", s[i][j]);
        printf("\n");
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值