前缀和数组
概念
前缀和是一种常用的数据结构,在计算机科学中经常被用于解决数组区间求和等问题。 前缀和数组是一个辅助数组,用于记录原数组从第0个元素到当前位置i处的所有元素的和
一维前缀和数组
for (int i = 1; i < n; i++) {
a[i] += a[i - 1];
}
二维前缀和数组
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (i == 0 && j == 0) {
p[i][j] = a[i][j];
} else if (i == 0) {
p[i][j] = p[i][j - 1] + a[i][j];
} else if (j == 0) {
p[i][j] = p[i - 1][j] + a[i][j];
} else {
p[i][j] = p[i - 1][j] + p[i][j - 1] - p[i - 1][j - 1] + a[i][j];
}
}
}
差分
概念
差分是一种常用的数据结构,在计算机科学中经常被用于对数组进行修改和查询。差分数组可以用来高效地对原数组的某个区间进行增减操作
一维差分
对于一维数组a,可以通过以下步骤构建其差分数组d:
- 初始化差分数组d为长度为n的全0数组。
- 对于要对原数组a的区间[l, r]进行增加一个值v的操作,可以执行以下操作 :d[l] += v d[r+1] -= v
-
构建差分数组后,可以通过遍历差分数组d,依次累加得到原数组a的元素:
a[i] = a[i-1] + d[i]
这样就实现了对原数组a的区间[l, r]的增加操作
二维差分
对于二维数组a,我们可以先按行构建每一行的差分数组,然后再对每一列的差分数组进行一维差分操作。
- 初始化差分数组d为二维数组,与原数组a的维度相同,全部初始化为0。
- 对于要对原数组a的区间[(x1, y1), (x2, y2)]进行增加一个值val的操作,可以执行以下操作:
- d[x1][y1] += val
- d[x2+1][y1] -= val
- d[x1][y2+1] -= val
- d[x2+1][y2+1] += val
构建差分数组后,可以通过遍历差分数组d,依次累加得到原数组a的元素:
a[i][j] = a[i-1][j] + a[i][j-1] - a[i-1][j-1] + d[i][j]
这样就实现了对原数组a的区间[(x1, y1), (x2, y2)]的增加操作
倍增
倍增算法是一种利用二进制表示和位运算来进行快速指数幂计算的技术,具有简单高效的特点,
倍增算法通常包括以下几个步骤:
-
将指数表示为二进制形式:将指数n转换为二进制形式
-
通过位运算进行指数幂计算:对于要计算的底数a,可以根据指数n的二进制形式,利用位运算来计算指数幂。具体做法是,从二进制表示中取出每一位,若为1,则累乘当前的幂值,然后底数平方,继续处理下一位