差分

Note

将原本需要通过遍历对区间求加和的时间 降低为

这种策略的定义是令

性质

  1. 的值是 的前缀和,即
  2. 计算 的前缀和
  3. 它可以维护多次对序列的一个区间加上一个数,并在最后询问某一位的数或是多次询问某一位的数。注意修改操作一定要在查询操作之前。

案例

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> 中

Reference