差分矩阵(二维差分)
一、算法描述
上一篇文章介绍了一维差分,本篇文章来介绍一下什么是二维差分。
含义
- 显然一维差分是一维前缀和的原数组,那么二维差分就是二维前缀和的原数组。
怎么求
- 跟一维一样,插入一遍即可,但是要注意每次插入要在同一个位置内插入,
insert(i, j, i, j, a[i][j]);
。
怎么用
-
一维差分是使得数组
在 范围内的数都加上 ,那么二维差分的作用就是使得 在 到 范围内的数都加上 。 -
差分操作的都是原数组
,通过 求一遍前缀和才能得到 ,也要注意我们操作的都是差分数组 ,那么我们如何操作 才能得到上面的效果呢? -
首先
b[x1][y1] += c;
,这样就会使得 到右下角所有的数都加上 ,然后有一些是不需要加但是加了的,所以要减回来,b[x2 + 1][y1] -= c, b[x1][y2 + 1] -= c;
,这样操作之后右下角有一块减了两次,所以还要再加回来一次,b[x2 + 1][y2 + 1] += c;
,这样就可以达到效果了,建议读者在草稿纸上画一下,更好理解。
代码如下:
void insert(int x1, int y1, int x2, int y2, int c)
{
b[x1][y1] += c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c;
}
二、题目描述
输入一个
每个操作都要将选中的子矩阵中的每个元素的值加上
请你将进行完所有操作后的矩阵输出。
输入格式
第一行包含整数
接下来
接下来
输出格式
共
数据范围
输入样例:
3 4 3
1 2 2 1
3 2 2 1
1 1 1 1
1 1 2 2 1
1 3 2 3 2
3 1 3 4 1
输出样例:
2 3 4 1
4 3 4 1
2 2 2 2
三、题目来源
四、源代码
#include <iostream>
using namespace std;
const int N = 1010;
int n, m, q;
int a[N][N], b[N][N];
void insert(int x1, int y1, int x2, int y2, int c)
{
b[x1][y1] += c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c;
}
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)
insert(i, j, i, j, a[i][j]);
while (q -- )
{
int x1, y1, x2, y2, c;
cin >> x1 >> y1 >> x2 >> y2 >> c;
insert(x1, y1, x2, y2, c);
}
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + b[i][j];
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j) cout << a[i][j] << ' ';
cout << endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!