Live2D

信息学中的差分

差分

差分是一种和前缀和有关的算法

我们来看看差分的定义

令a数组为:1 2 3 1 2 3
那么差分数组b为: 1 1 1 -2 1 1
令a[0] = 0
那么b[i] = a[i] - a[i - 1]


算法解析:

现在要更新数组a的(x1~x2)位:将其增加k
我们可以将b[x1]增加k, 并且将b[x2 + 1]减少k
为什么呢,现在来证明一下算法的正确性:
不妨设n = 10, x1 = 3, x2 = 6
\(\because\Delta a[3] = \Delta a[4] = \Delta a[5] = \Delta a[6] = k\)
\(\therefore\Delta b[4] = \Delta b[5] = \Delta b[6] = 0\)
\(\because[3,6]\)这段区间中所有的数都增加了k
\(\therefore\Delta (a[3] - a[2]) = k, \Delta (a[7] - a[6]) = -k\)
\(\Delta b[3] = k, \Delta b[7] = -k\)


代码示例:

a[0] = 0;
for(int i = 1; i <= n; i ++) a[i] = read();
for(int i = 1; i <= n; i ++) b[i] = a[i] - a[i - 1];
for(int i = 1; i <= m; i ++) {
      int x1 = read(), x2 = read(), k = read();
      b[x1] += k, b[x2 + 1] -= k;
}
for(int i = 1; i <= n; i ++)
      b[i] += b[i - 1];
for(int i = 1; i <= n; i ++)
      cout << b[i] << ' ';

Input:

5 5
1 2 3 4 5
1 3 5
2 2 4
3 5 8
2 3 1
3 4 2

Output:

6 12 19 14 13

口算:

  1. 6 7 8 4 5
  2. 6 11 8 4 5
  3. 6 11 16 12 13
  4. 6 12 17 12 13
  5. 6 12 19 14 13
    完全正确,可见算法正确性
    (看我打那么辛苦就点个赞吧)
posted @ 2020-09-04 21:20  Wuzhouming  阅读(356)  评论(0编辑  收藏  举报