前缀和与差分算法
前缀和算法好处:能实现O(1)时间复杂度内计算和
注意:
为处理边界问题,统一从下标1开始读入,且a[0] = 0
、
使得求区间之和有统一的公式S[i] - S[j - 1]
一维前缀和
cpp
1 | const int N = 100000; |
二维前缀和
表示在当前格子[i,j]
左上方所有数之和
基本公式:
计算特定区间内一段方格的和:s[x2, y2] - s[x1 - 1, y2] - s[x2, y1 - 1] + s[x1 - 1, y1 - 1]
计算s[i][j]:s[i,j] = s[i - 1, j] + s[i,j - 1] - s[i - 1, j - 1] + a[i, j]
cpp
1 | const int N = 1000; |
#差分
差分是前缀和的逆运算
一维差分
应用举例:
将A数组的[l, r]
区间全部加上一个常数c,如果使用暴力计算的时间复杂度为O(n),而如果使用差分算法,只需要对A数组的差分数组B进行如下处理:B[l] += c
, B[r + 1] -= c
,而此时的时间复杂度为O(1)
对于A数组,构造一个数组B使得B成为A数组的差分数组:
基本思想:
将A数组中的第i个元素视为在A数组的[i, i]
区间插入数值为A[i]
的数
cpp
1 | void(int l, int r, int c) |
二维差分
二维矩阵的差分计算,如果在某一区间[x1, x1][x2, y2]
增加一个常量c,那么只需要
cpp
1 | b[x1][y1] += c; |
初始化和一维差分矩阵的插入类似,只需要视为在[i, j][i, j]
插入一个值为c的数