zoukankan      html  css  js  c++  java
  • 可持久化树套树 (细节) 笔记

    假设已经会了树套树和可持久化权值线段树 (主席树)

    昨天晚上在机房里面写,发现我有一些细节问题不是很懂,并且对这个玩意理解的也不太行

    一些约定

    有一个树套树,内外都是权值线段树。

    对于一个外层树上的点 (u),称左右儿子为 (ls(u),rs(u)),并且套着一个内层树 (T(u))(T(u)) 的根是 (rt'(u))

    对于一个内层树上的点 (u),称左右儿子为 (ls'(u),rs'(u)),并且维护了一些信息。

    对于一个线段树,设位置 (x) 的影响路径为,从根一路找,找到单点 (x),经过的路径(包括根 ([1,n])([x,x])

    例如 (n=5) 时,(x=2) 的影响路径为 ([1,5],[1,3],[1,2],[2,2]) 对应的点。

    正片

    有这样一个二维数点问题:加入一个点,询问矩形里点的信息(个数/和/max)。很明显可以树套树做。

    这样的问题,如果要支持历史版本的询问,如何做?

    即,我们要询问:如果只插入了前 (i) 个点,矩形信息。

    考虑可持久化。相当于每个版本都有一个树套树。那首先我们肯定要把外层可持久化。

    (rt(i)) 表示第 (i) 个版本的外层树的根。考虑 (i-1) 版本到 (i) 版本的变化,很明显是多了一个点 ((x,y))

    根据树套树,我们需要在外层的树上找到 (x) 位置的影响路径。对于影响路径上的所有点,它们套的内层树 (T) 都要在 (y) 位置做插入。

    现在我们要可持久化这个过程。类似主席树,用 path copy 的思想:在外层树上把 (x) 的影响路径给copy一份。对于路径上的每个点,要修改的那个儿子就递归做,不要修改的那个儿子直接继承原树。

    考虑复制的时候怎么快速维护。设它影响路径上有个点 (u),我们把它复制到 (u')。那么 (T(u')) 就是 (T(u)) 加上一个 (y) 位置的插入。

    只有这个内层树操作是不好做的,剩下的操作都比较simple。考虑一下,我们相当于要支持:

    • 有若干颗树
    • 每次给 (i,j,x),令 (j) 这颗树为 (i) 这颗树插入一个 (x) 位置
    • 要求维护每棵树的信息

    注意到这玩意也可以用可持久化做,把 (i,j) 看成版本就行了。

    那我们内层也要维护一个可持久化树,来支持这个操作。

    例题: bzoj3489

    转换一下问题,设 (pre,suf) 表示前一个/后一个和当前相同的位置。问题变为:

    有若干点 ((i,pre_i,suf_i)),每次给 (l,r),求满足:(iin[l,r],pre_i<l,suf_i>r) 的点中,最大的 (a_i)

    注意到 (pre) 这一维是一个 (<),把它看成是版本,维护一个可持久化树套树。树套树里面维护 ((i,suf_i)) 两维

    然后就搞一个可持久化的树套树求矩形max就行了。

    时空复杂度均为 (O(nlog^2 n))

    代码

  • 相关阅读:
    UITableview cell 的多选
    抽屉开关控制器
    NSDate 获取明天、后天的日期
    UITextField里面的 placeholder颜色和字体
    判断返回数据是否为 null
    UIButton 长按点击 背景改变效果
    UIButton 去除按下效果(阴影)
    iOS-RunLoop,为手机省电,节省CPU资源,程序离不开的机制
    iOS-真机调试
    iOS-设置启动图片
  • 原文地址:https://www.cnblogs.com/LightningUZ/p/15239624.html
Copyright © 2011-2022 走看看