前缀和与差分
前缀和与差分
1、一维前缀和
描述:
可以在O(1)的时间算出一段区间内的所有数的和。
模板:
1 |
|
注意:
前缀和与差分数组下标都必须从1开始。
2、二维前缀和
描述:
能够在O(1)的时间内算出一个矩阵中所有数的和。
思路:
(1)数组下标都从1开始,便于后续的处理
(2)遍历二维数组中的每一个点
构造:每一个点执行s[i][j] = s[i - 1][j] + s[i][j - 1] + a[i][j] - s[i - 1][j - 1];
(3)获取(x1, y1)与(x2, y2)之间的子矩阵的所有数的和
构造完成后的二维前缀和数组,直接输出
s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1],即可获得该子矩阵的所有数的和
代码模板:
1 |
|
3、一维差分
描述:
用于给某个区间快速地加上或者减去某个数。
思路:
(1)构造差分数组
(1.1)将差分数组看作原本都是0,a[i]是原数组,b[i]是差分数组
(1.2)然后将原数组中的每一个数,都插入到差分数组中,
b[l] += c, //a[l]后的数都会+c
b[r + 1] -= c; //a[r + 1]后的数都会-c,【补丁】
最后达到的效果就是a[l] ~a[r]之间的每一个数都加上了c
(2)然后根据题目要求在差分数组中指定区间中的每一个数都加上一个数,即在差分数组中的该区域中插入该数
(3)将差分数组还原成原数组(前缀和数组)输出即可 b[i] += b[i - 1];
代码模板:
1 |
|
4、二维差分
描述:
快速地将一个矩阵中所有数全部加上或者减去一个数,并求出多次操作后的结果。
思路:
(1)差分矩阵的构造:
(1.1)将差分数组看作全部都是0,将原数组中的数处理后,一个一个插入到差分数组中
(1.2)先全部上c,再将不需要加上c的地方进行补丁,即减去c
b[x1][y1] += c; //以(x1, y1)为左上角顶点的所有矩阵中的元素全部加上了c这个数
b[x2 + 1][y1] -= c; //以(x2 + 1, y1)为左上角顶点的所有矩阵中的元素全部减去了c这个数
b[x1][y2 + 1] -= c; //以(x1, y2 + 1)为左上角顶点的所有矩阵中的元素全部减去了c这个数
b[x2 + 1][y2 + 1] += c; //以(x2 + 1, y2 + 1)为左上角顶点的所有矩阵中的元素加上c这个数,前面多减了一次
(2)然后根据题目要求在差分数组中指定区间中的每一个数都加上一个数,即在差分数组中的该区域中插入该数
(3)将差分数组还原成原数组(前缀和数组)输出即可
b[i][j] += b[i][j - 1] + b[i - 1][j] - b[i - 1][j - 1];
代码模板:
1 |
|