1、一维差分
首先要知道,差分是前缀和的逆运算,
a1 a2 …… an 前缀和
b1 b2 …… bn 差分
以AcWing.797为例,题目要求如下:
输入一个长度为 n 的整数序列。
接下来输入 m 个操作,每个操作包含三个整数 l, r, c ,表示将序列中 [l,r] 之间的每个数加上 c 。
请你输出进行完所有操作后的序列。
输入格式:
第一行包含两个整数 n 和m 。
第二行包含 n 个整数,表示整数序列。
接下来 m 行,每行包含三个整数l,r,c ,表示一个操作。
输出格式:
共一行,包含 n 个整数,表示最终序列。
#include <iostream> using namespace std; const int N = 1e5 + 10; int a[N], b[N]; void insert(int l, int r, int c) { b[l] += c; b[r + 1] -= c; } int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); insert(i, i, a[i]); } while (m--) { int l, r, c; scanf("%d%d%d", &l, &r, &c); insert(l, r, c); } for (int i = 1; i <= n; i++) { b[i] += b[i - 1]; printf("%d ", b[i]); } return 0; }
2、二维差分
二维差分需要用到二维矩阵和的思想。
以ACWing.798为例,题目要求如下:
输入一个n行m列的整数矩阵,再输入q个操作,每个操作包含五个整数x1, y1, x2, y2, c,
其中(x1,y1)和(x2,y2)表示一个子矩阵的左上角坐标和右下角坐标。
每个操作都要将选中的子矩阵中的每个元素的值加上c。
请你将进行完所有操作后的矩阵输出。
输入格式:
第一行包含整数n,m,q。
接下来n行,每行包含m个整数,表示整数矩阵。
接下来q行,每行包含5个整数x1,y1,x2,y2,c,表示一个操作。
输出格式
共n行,每行m个整数,表示所有操作进行完毕后的最终矩阵。
#include <iostream> const int N = 1010; 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() { 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("%d", &a[i][j]); insert(i, j, i, j, a[i][j]); } } int x1, y1, x2, y2, c; while (q--) { scanf("%d%d%d%d%d", &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++) { b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1]; printf("%d ", b[i][j]); } printf("\n"); } return 0; }
标签:int,整数,x2,二维,差分,一维,y1,y2 From: https://www.cnblogs.com/karinto/p/17720990.html