差分
Note
将原本需要通过遍历对区间求加和的时间 降低为
这种策略的定义是令
性质
- 的值是 的前缀和,即
- 计算 的前缀和
- 它可以维护多次对序列的一个区间加上一个数,并在最后询问某一位的数或是多次询问某一位的数。注意修改操作一定要在查询操作之前。
案例
Example
给定一个数组:[0, 0, 0, 0, 0, 0]
- 在 位置上执行 +2:
- 得到差分数组:
- 通过求前缀和可以直接得到原数组:
- 在 位置上执行 +2;在 位置上执行 +1;在 位置上执行 -3;
- 得到差分数组:
- 通过求前缀和可以直接得到原数组:
- 得到差分数组:
Example
给定一个数组:[1, 2, 3, 4, 5, 6]
- 在 位置上执行 +3;在 位置上执行 -2;
- 求得原数组的差分数组:
- 执行操作:
Tip
为什么需要在下一个位置上执行反操作?
- 我们抽象出需要执行增长的项:
- 然后我们知道在求解前缀和的过程中,区间内的每一项都执行 操作;
- 但是区间之外就无需再进行增长,如何抵消呢?
- 在区间之外(右边界的下一个位置)取一个 操作;🎉
进阶
- 抽象一点的公式是这样的:
- 譬如使 中的每个数加上一个 ,即
- 其中 ,
- 最后做一遍前缀和就好了
- 譬如使 中的每个数加上一个 ,即
- cpp 实现了差分函数
std:adjacent_difference,定义于头文件<numeric>中