• 差分数组原理与其前缀和的应用


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

    例如这里有 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] 的影响。

  • 相关阅读:
    聚焦LSMIMO的四大层面,浅谈5G关键技术
    基于LiteOS Studio零成本学习LiteOS物联网操作系统
    使用LiteOS Studio图形化查看LiteOS在STM32上运行的奥秘
    GaussDB(DWS)应用实践丨负载管理与作业排队处理方法
    GaussDB(DWS)磁盘维护:vacuum full执行慢怎么办?
    从物理空间到数字世界,数字孪生打造智能化基础设施
    Lab 4 : OpenFlow
    SDN控制器拓扑发现(一)
    pxe dhcp
    RyuBook1.0案例二:Traffic Monitor项目源码分析
  • 原文地址:https://www.cnblogs.com/Absofuckinglutely/p/11342005.html
Copyright © 2020-2023  润新知