B 二维差分
Subject: 输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将选中的子矩阵中的每个元素的值加上 c。 请你将进行完所有操作后的矩阵输出。 1≤n,m≤1000,1≤q≤100000,1≤x1≤x2≤n,1≤y1≤y2≤m,−1000≤c≤1000,−1000≤矩阵内元素的值≤1000
-
步骤:
1.给定
a[h][l]
构造b[h][l]
,使a[h][l]=b[1][1]+b[1][2]+...+b[1][l]+b[2][1]+...b[h][l]
。
2.对子矩阵(x1,y1)~(x2,y2)
进行+-c操作:
b[x1][y1]+=c
b[x2+1][y1]-=c
b[x1][y2+1]-=c
b[x2+1][y2+1]+=c
3.算前缀和输出a[][]
。 a[x][y]=a[x-1][y]+a[x][y-1]-a[x-1][y-1]+b[x][y]
.
eg.
#include<stdio.h>
int a[1009][1009], b[1009][1009];
void insert(int x1, int y1, int x2, int y2, int c)
{
b[x1][y1] += c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y1] -= c;
b[x2 + 1][y2 + 1] += c;
}
int main()
{
int n, m, q, h, l, i, x1, x2, y1, y2, c;
scanf("%d %d %d", &n, &m, &q);
for (h = 1; h <= n; h++)
{
for (l = 1; l <= m; l++)
{
scanf("%d", &a[h][l]);
insert(h, l, h, l, a[h][l]);//初始化b[][].
}
}
while (q--)
{
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &c);
insert(x1, y1, x2, y2, c);
}
for (h = 1; h <= n; h++)
{
for (l = 1; l <= m; l++)
{
a[h][l] = a[h - 1][l] + a[h][l - 1] - a[h - 1][l - 1] + b[h][l];//求前缀和a[][]
printf("%d ", a[h][l]);
}
printf("\n");
}
return 0;
}