zoukankan      html  css  js  c++  java
  • 差分数组原理与其前缀和的应用

    看字你就应该知道,差分数组存的是什么了,即存的是每一项与前一项的差值。

    例如这里有 A[] 数组:

    A[] = 0  1  3  8  4  5  7 ( 下标从 0 开始,A[0] 为 0 )

    根据 D[i] =  A[i] - A[i-1],我们可以得到 D[] 数组:

    D[] = 0  1  2  5  -4  1  2

    直观的,我们可以看出:

    D[0] + D[1] =  A[1] = 1

    D[0] + D[1] + D[2] = A[2] = 3

    D[0] + D[1] + D[2] + D[3] = A[3] = 8

    .........................................................

    嗯,所以得到的 D[] 数组,再求一下前缀和,就可以知道 A[i] 的值了。

    那这样有什么好处呢?

    这样就可以 O(1) 处理区间更新,然后就能很快的求解单点查询了

    还是上面的例子,现在我们使区间 [3,5] 全部加上 2 

    然后你这样想:如何处理 D 数组,使得:

    D[1] + D[2] + D[3] = A[3] + 2

    D[1] + D[2] + D[3] + D[4]= A[4] + 2

    D[1] + D[2] + D[3] + D[4] + D[5] = A[5] + 2

    为了满足上面三个式子,我们应该使: D[1] += 2 或者 D[2] += 2 或者 D[3] += 2 

    然而如果是 D[1] += 2 或者 D[2] += 2 的话,那我现在用 D 数组求 A[1] 或者 A[2] 的话,不就错了吗?

    所以我只能使得 D[l] += 2 ,即这里的 D[3] += 2 ,这样我即可以 O(1)修改区间 [3,5],又不会使 1 ~ l 的运算出错。

    同样!为了保证用 D 数组求 A[r+1] A[r+2] ..... 时不出错,我们必须消除 加 2 对他们的影响,因为 只是 [3,5] 加了 2 。

    跟上面的思路一样,必须消除影响,即需要在 D[r] 或者 D[r+1] 、D[r+2] 的时候减去 2 ,这样前缀和时,加 2 减 2 消掉了,不会给后面造成影响。

    那么如果 D[r] -= 2 ,算 A[r] 的时候就错了,因为这相当于 A[r] 没有更新 加 2 。

    如果 D[r + 2] 减 2 的话,会使得算 A[r + 1] 的时候算错,因为这相当于 A[r + 1] 加了 2 。在 D[r + 3] 、D[r + 4] ......减 2 同理,都不行。

    综上:我们需要在 D[l] += k ,D[r + 1] -= k ,以便保证算 [l,r] 的时候不会错,也消除了算[1,l] 和 [r + 1,n] 的影响。

  • 相关阅读:
    剑指offer 顺时针打印矩阵
    剑指offer队列中的最大值
    固定顶部指定div不滑动
    调整圆环统计图格式
    补插一个MUI中UI组件示例地址
    统计图左右滑动
    mui集成百度ECharts的统计图表以及清空释放图表
    页面ajax自带的访问后台时,正在加载中
    js弹出div层内容(按回退键关闭div层及遮罩)
    地图经纬度定位不准
  • 原文地址:https://www.cnblogs.com/Absofuckinglutely/p/11342005.html
Copyright © 2011-2022 走看看