zoukankan      html  css  js  c++  java
  • 线段树入门

    一、引入

    1.我想单点查询序列的值,怎么办?
    当然是来一个数组啦!

    2.我想单点查询序列的值,还想单点修改,怎么办?
    还是数组!

    3.我想区间求和(后文称为查询),怎么办?
    维护一个前缀和,(sum[i]=sum_{j=1}^ia[i])就可以(O(1))查询。

    4.我想区间求和,还想单点修改,怎么办?
    退役吧。。

    如果你至今还抱着万物皆可(O(1))的幻想,那就(Too\,young\,too\,simple)了。

    我来帮你复习一下:

    1.OI( o)计算机( o)二进制( o O(log_2n))

    2.(OI o ext{(幻视)} 01 o ext{二进制}) ( o) (O(log_2n))

    “二进制”思想在算法中应用广泛,从二分到倍增等,都化(n)(log_2n),避免了被卡飞的惨剧。所以就有了神奇的树状数组。

    【注:你说差分?太强了,没听说过。】

    二、定义

    5.现在毒瘤出题人要求你区间查询,区间修改。这类问题可以用线段树来解决。
    听说你树状数组很6,甚至还会差分??


    【注:图片来自百度百科,但是看上去百度百科也是侵权的w我就不删了】

    图中的巨型树状物就是一颗线段树。也就是说,将一个大区间取中点得到小区间,组成一颗二叉树,这就叫线段树。

    三、毒瘤操作

    1.区间查询

    这和树状数组大同小异。将大区间拆成至多(log_2n)个小区间(n为区间总长),就可以拼凑出答案。实现方法是分治:如果孩子区间与所求区间有重叠,就继续向下查询,直到孩子区间包含在所求区间内,此时累加答案。

    2.区间修改

    woc这是(O(n))!

    还真的是。那怎么办呢?我们先不考虑这个问题。

    2.1单点修改很水

    直接将对应的(log_2n)个节点修改就好了。
    学到这里,你应该能A一道模板题了。

    2.2我好想和区间查询一样快啊

    对于一个不在线段树最底层的区间,在修改时,我们要把他的孩子一起更新。此时应该思考两个问题:

    (1)如果我不用查询,更新孩子干嘛?

    (2)如果我修改上了瘾,为什么不能把修改的内容累计,等到最后一起修改?

    它们分别说明:

    (1)要查询了,再来修改。

    (2)不查询时,记录修改即可。

    于是我们对于每一个节点,都记录一个标记(tag),在更新时只修改父亲节点的值,并把修改的内容记录到(tag)里。当查询到该节点时,顺手把子节点更新并下传标记。这样就不用连着孩子更新。
    模板题

    四、模板++

    有时候维护的内容较多,就需要更复杂的代码。当然这些也属于模板题。

    比如

    (19-7-21未完待续)

  • 相关阅读:
    9天C#转Java学习过程,自己记录一下
    【分享】我们用了不到200行代码实现的文件日志系统,极佳的IO性能和高并发支持,附压力测试数据
    微信公众号第三方平台开发坑
    分享我们团队最近开发的微信公众号运营助手,可以在手机上回复粉丝留言
    分享一波会眨眼的壁纸
    idea连接服务器上传jar并运行
    ngnix简单使用
    IntelliJ IDEA简介及简单操作
    eclipse开发创建web项目
    myeclipse/eclipse 配置SSM框架错误之一解决方法
  • 原文地址:https://www.cnblogs.com/ehznehc/p/11221247.html
Copyright © 2011-2022 走看看