前缀和&差分
一维前缀和
- 前缀和即为数组的前n项和
presum[i]=a[1]+a[2]+...+a[i]
- 区间查询
- 求的区间和为:
presum[r]-presum[l-1]
- 求的区间和为:
1 | for(int i=1;i<=n;i++) |
二维前缀和
s[i][j]
表示二维数组中,左上角(1,1)
到右下角(i,j)
所包围的矩阵元素的和- 预处理
1 | for(int i=1;i<=n;i++) { |
- 区间查询
- 查询以
(x1,y1)
为左上角,(x2,y2)
为右下角的矩形元素之和
- 查询以
1 | int sum = s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]; |
差分
- 差分是前缀和的逆运算。
- 差分数组
b[i]=a[i]-a[i-1]
,b[0]=a[0]
1 | for(int i=1;i<=n;i++) { |
- 对差分数组求前缀和即可还原数组
- 区间更新
- 对a数组区间的数都加上
1 | b[l]+=c; |
- 将更新封装成一个函数
1 | void insert(int l,int r,int c) { |
- 构建差分数组则为
1 | for(int i=1;i<=n;i++) { |
二维差分
- 构造二维差分数组目的是为了 让原二维数组
a
中所选中子矩阵中的每一个元素加上c
的操作,可以由O(n*n)
的时间复杂度优化成O(1)
- 区间更新,对
a[x1,y1]~a[x2,y2]
的矩形区域加上c
1 | void insert(int x1,int y1,int x2,int y2,int c) { |
- 构造二位差分
1 | for(int i=1;i<=n;i++) { |