假设已经会了树套树和可持久化权值线段树 (主席树)
昨天晚上在机房里面写,发现我有一些细节问题不是很懂,并且对这个玩意理解的也不太行
一些约定
有一个树套树,内外都是权值线段树。
对于一个外层树上的点 (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))。