差分

本算法题来自acwing 97. 差分 ,以下是要求

要求

输入一个长度为 n 的整数序列。

接下来输入 m 个操作,每个操作包含三个整数 l,r,c,表示将序列中 [l,r]之间的每个数加上 c。

请你输出进行完所有操作后的序列。

输入格式: 第一行包含两个整数 n 和 m 。

第二行包含 n 个整数,表示整数序列。

接下来 m 行,每行包含三个整数 l,r,c ,表示一个操作。

输出格式: 共一行,包含 n 个整数,表示最终序列。

输入样例: 6 3 1 2 2 1 2 1 1 3 1 3 5 1 1 6 1

输出样例: 3 4 5 3 4 2

算法代码

const N = 100010;
let n, m;
let a = new Array(N);  // 存储初始数组
let b = new Array(N);  // 存储差分数组

function insert(l, r, c) {
  // 将区间[l, r]中的元素加上c
  b[l] += c;
  b[r + 1] -= c;
}

function main() {
  // 读入n,m
  let input = readline().split(' ').map(Number);
  n = input[0], m = input[1];  //控制台输入的值

  // 读入初始数组a
  input = readline().split(' ').map(Number);
  for (let i = 1; i <= n; i++) {
    a[i] = input[i - 1];
  }

  // 对差分数组b进行预处理,初始化为初始数组a
  for (let i = 1; i <= n; i++) {
    insert(i, i, a[i]);
  }

  // 对m个操作进行处理
  while (m--) {
    input = readline().split(' ').map(Number);
    let l = input[0], r = input[1], c = input[2];
    insert(l, r, c);  // 将区间[l, r]中的元素加上c
  }

  // 根据差分数组b求出最终数组c
  for (let i = 1; i <= n; i++) {
    b[i] += b[i - 1];
  }

  // 输出最终数组c
  console.log(b.slice(1, n + 1).join(' '));
}

main();
假设原始数组为 [4, 6, 7, 8], 差分数组为 [4, 2, 1, 1]。

对差分数组 b 求前缀和,得到:

c[1] = b[1] = 4

c[2] = b[1] + b[2] = 6

c[3] = b[1] + b[2] + b[3] = 7

c[4] = b[1] + b[2] + b[3] + b[4] = 8

对比一下原始数组,可以看到:

第一项:a[1] = 4,而 c[1] = b[1] = 4,相同。

第二项:a[2] = 6,而 c[2] = b[1] + b[2] = 4 + 2 = 6,相同。

第三项:a[3] = 7,而 c[3] = b[1] + b[2] + b[3] = 4 + 2 + 1 = 7,相同。

第四项:a[4] = 8,而 c[4] = b[1] + b[2] + b[3] + b[4] = 4 + 2 + 1 + 1 = 8,相同。

所以可以发现,前缀和数组 c 就是原始数组 a,其差分数组 b 就是相邻两项之差。
···