【水文】全局平衡二叉树的几个补充
yangzhe1990 · · 算法·理论
最近看到 OI 界有 top tree、仙人掌、广义串并联图等高级的东西,大开眼界。也看到全局平衡二叉树成为了常见/用数据结构之一。其发明时的需求还比较简单,现在进行几个简单的没什么大用处的补充。毕竟这是个静态的数据结构,只处理路径问题的话斜二倍增真是独具一格。
本文很水。先水一下为什么全局平衡二叉树的构造一定要用加权的二叉树。
卡线段树维护的树链剖分
考虑一棵左偏的二叉树。左儿子是长度为
全局平衡二叉树的几个补充
剖分方式的修改
对树上每个结点
这样修改后对于结点儿子较多的树更加友好,总深度更浅更平衡。二叉树的
一个不够好的剖分方案
这里
最多
所以刚才那个改版的重量定义已经很好了,还是在说明全局平衡二叉树的魔改空间有限。
子树操作
子树操作涉及到用某个数据结构维护轻儿子森林,不能使用上文简化的重量作为剖分和加权的依据。需要使用原版的轻儿子森林总结点数(是否
如果子树操作足够简单,用上文简化的重量作为剖分方式或许可行。例如整体染色之类的,不需要用数据结构维护轻儿子森林。但是当你思考这个子树操作全局平衡二叉树是不是做不了的时候,肯定不属于这个情况了。
子树无序的情况
若干篇提到全局平衡二叉树的文章也提到了子树操作。例如树分治小记中提到
如果将同一个点上挂着的轻儿子,同样使用加权二叉树维护,似乎就能够做到子树操作
可以选最重子树
森林跟轻节点列表类似,也可以用这样的方法作为顶端结构来维护,唯一差别是森林中可能有一颗“重树”,但不需要特殊处理。
子树有序的情况
如果将同一个点上挂着的轻儿子,同样使用加权二叉树维护,似乎就能够做到子树操作
这就能保证深度在
轻节点要根据所规定的顺序分列重结点的左右,在重链建树过程中,一些轻结点最终挂在重链构建的树中的位置其实是它父亲的某个子孙。
子树有顺序规定时的建树方式最终的样子有些非对称:
考虑重链建树之后树上的每个重结点,如果一个重结点在最左分枝上,它将会挂上这些附加结构:“祖先先序轻森林所建平衡树结构”、“左侧轻儿子森林所建平衡树结构”(可以考虑不设此结构,将其合并到重链所建树的左儿子的“祖先先序轻森林所建平衡树结构”中)、“右侧轻儿子森林所建平衡树结构”;
其余重结点只有一个附加的“右轻儿子森林所建平衡树结构”。或许应当把重链建树之后的最左分枝看作“中轴线”了。
既然“祖先先序轻森林所建平衡树结构”是从右子树抽出来重建的一个结构,其实有多种构建方式。如果树的顺序设置之中,根结点先于子树,即是先序设置,还需要考虑“祖先先序”之中的每个祖先重结点。因此我不太喜欢刚才写的这个名字,不如改为“祖先先序树”。每个先序的祖先重结点也有多种方式加入到“祖先先序树“之中。例如加一个特殊标记到最左轻儿子上(如有)。
但我不喜欢这些不同重结点的儿子轻森林变成同一层进行建树的方法。按照原本没考虑子树顺序的建立重链平衡树的方法,右子树深度的性质已经是对数级别了,因此“祖先先序树”应当存在一种镜像建树的方法,既保证深度的对数级别,又能保持结构的优美。
因此,这个结构可以仍然是以重结点组成的链,每个重结点下方挂着一些左轻儿子来建树,只不过这条链不再具有重链的意义了,只保留“先序祖先”的意义。尽管重结点似乎被用了两份,也不需要担心树的
重链建树的权重计算可以不作修改,因为按原算法所得的“祖先先序轻森林所建平衡树结构”本身是从右子树中抽出来的一个部分结构,