思路

差分是前缀和的逆运算

即对差分数组求一遍前缀和就可以得到原数组

其最主要的操作是: 将原数组中一个范围的数都加上(或减去)某个值,并且实现 的时间复杂度

实现为,在对应处b[i] + x 另外在 范围终点 b[r+1] - x 来保证之后的数不会加上这个x

本来需要每个原数组元素都加上 x 的操作,现在优化为只有两个数加上 x

实现

void insert(int l, int r, int x)
{
	b[l] += x;
	b[r+1] -= x;	
}

差分矩阵

B数组的前缀和就是A数组

#include <iostream>
#include <algorithm>
 
using namespace std;
 
 
const int N = 1e3 + 10;
 
 
int b[N][N];
int a[N][N];
 
 
void 
insert(int l1, int r1, int l2, int r2, int c)
{
    b[l1][r1] += c;
    b[l1][r2 + 1] -= c;
    b[l2 + 1][r1] -= c;
    b[l2 + 1][r2 + 1] += c;
}
 
int
main()
{
    int n, m, q, x, y, l, r, c;
    cin >> n >> m >> q;
    
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= m; j ++)
        {
            cin >> a[i][j];
            insert(i, j, i, j, a[i][j]);
        }
    }
    
    while(q --)
    {
        cin >> x >> y >> l >> r >> c;
        
        insert(x, y, l, r, c);
    }
    
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= m; j ++)
        {
            b[i][j] = b[i - 1][j] + b[i][j - 1] + b[i][j] - b[i - 1][j - 1]; 
        }
    }
    
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= m; j ++)
            printf("%d ", b[i][j]);
        puts("");
    }
    
    return 0;
}