前缀和、差分、离散化与堆
\text{1 前缀和}
\text{1.1 前缀和的定义}
前缀和算法是一种常用的优化技术,用于加速某些涉及连续子数组或子序列求和的问题。它基于一个简单但强大的思想,通过提前计算并存储数组的前缀和,以便在后续查询中可以快速获取任意区间的和。
在许多算法问题中,我们需要频繁地查询子数组的和,例如最大子数组和、连续子数组的平均值等。传统的方法是在每次查询时遍历数组,并计算所需区间的和,这样会导致时间复杂度较高。
而前缀和算法通过预处理数组,计算出每个位置的前缀和,并将其保存在一个额外的数组中。这样,在查询时,我们只需要简单地减去两个前缀和即可得到所需子数组的和,从而将查询时间降低为
\text{1.2 使用前缀和的方法}
前缀和算法是一种用于高效计算数组前缀和的算法。前缀和是指数组中某个位置之前(包括该位置)所有元素的和。
前缀和算法的基本思想是通过一次遍历数组,计算每个位置的前缀和,并将其存储在一个新的数组中。然后,可以通过查询新数组中的元素,快速计算出任意子数组的和。
具体步骤如下:
- 创建一个新的数组
q ,长度与原数组相同。 - 初始化
q[1] 为原数组的第一个元素。 - 从原数组的第二个元素开始,依次计算
q[i] = q[i-1] + a[i] ,其中a 为原数组。 - 完成后,
q 数组中的每个元素即为对应位置之前所有元素的和。
通过前缀和算法,可以在
如上,如果要求原数组中
特别的,在建立时需要把第
前缀和算法在解决一些与子数组和相关的问题时非常有用,例如求解子数组和等于目标值的个数、求解最大子数组和、求解最长连续子数组和等。
\text{1.3 二维前缀和}
二维前缀和的建立:
\text{2 差分}
模板题:
\text{2.1 差分的定义}
差分其实就是前缀和的逆运算。
对于一个数组
对差分数组做前缀和可以还原为原数组。
\text{2.2 使用差分的方法}
利用差分数组可以实现快速的区间修改。
如何将区间
如上图,当我们将原数组
所以说,在差分数组中将区间
c[l] += x;
c[r+1] -= x;
但是注意:差分数组不能实现“边修改边查询(区间和)”,只能实现“多次修改完成后多次查询”,因为查分查询的时间复杂度为
\text{3 离散化}
其法有三:
-
- 排序,去重,二分;
- 哈希(散列表).
排序、去重的常用方法:
sort(a+1, a+n+1);
int n_copy = n;
n = unique(a+1, a+n+1)-a-1;
\text{4 堆}
- 堆是一种完全二叉树。
- 堆要求孩子节点要小于等于父亲节点(大顶堆)