前缀和与差分
一.一维前缀和
递推公式:prefixi = prefixi-1 + arri-1(下标从1开始)
区间和计算:suml, r = prefixr - prefixl-1
时间复杂度:O(n)
空间复杂度:O(n)
二.一维差分
dL+=cdL += cdL+=c
dR+1−=cdR+1 -= cdR+1−=c(若 R+1>nR+1 > nR+1>n 则忽略)
通过一维前缀和还原
三 . 二维前缀和
cpp
pre[i][j] = a[i][j] + pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1]
解释:
mat[i][j]是当前元素
pre[i-1][j]是上方矩形区域的和
pre[i][j-1]是左侧矩形区域的和
pre[i-1][j-1]是被重复计算的部分,需要减去
查询
cpp
sum = pre[x2][y2] - pre[x1-1][y2] - pre[x2][y1-1] + pre[x1-1][y1-1]
解释:
prex2y2是整个大矩形区域的和
减去上方不需要的区域prex1-1y2
减去左侧不需要的区域prex2y1-1
加上被重复减去的左上角区域prex1-1y1-1
四 . 二维差分
cpp
D[x1][y1]+=c // 影响右下所有区域
D[x1][y2+1]−=c // 抵消右侧多余区域
D[x2+1][y1]−=c // 抵消下方多余区域
D[x2+1][y2+1]+=c // 补偿重复抵消区域
原理:通过四个位置的增减,使修改仅作用于目标子矩阵(容斥原理)
cpp
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
D[i][j] = A[i][j] - A[i-1][j] - A[i][j-1] + A[i-1][j-1];