LCT(动态树)(洛谷P3690)(BZOJ3282)

本文详细介绍了动态树LCT的概念、用途、算法实现及其操作,包括Access、MakeRoot、Cut、Link等,并提供了复杂度证明。LCT主要用于解决动态维护有根树森林的问题,支持查询路径权值和、LCA、单点修改等操作。文章以洛谷P3690(BZOJ3282)题目为例,给出LCT的模板代码。
摘要由CSDN通过智能技术生成

推荐这篇论文

前置技能

Splay树链剖分

简介

动态树问题, 简称LCT,近几年在OI中兴起的一种新型问题,是一类要求维护一个有根树森林,支持对树的分割, 合并等操作的问题。

算法用途

比如维护一个数据结构,有如下操作:

1.查询路径权值和。
2.查询LCA。
3.修改单个点的权值。
4.断开两个点,使之成为两棵树。
5.合并两个点,使之成为一颗树。

当然还可以有关于子树的操作,但是这个需要用到另一种数据结构叫TopTree。这里暂时只讲LCT。

算法实现

几个定义

Preferred Child:在v的子树中,如果最后被访问的节点在子树w中,则称w是v的Preferred Child。特殊的,如果最后被访问的节点就是v本身,则v没有Preferred Child。

Preferred Edge:连接v与其Preferred Child的边。

Preferred Path:由Preferred Edge构成的不可再延伸的路径。

Path Parent:Preferred Path中最高点的父亲节点。特殊的,如果这条Preferred Path的最高点就是根节点,则这条Path没有Path Parent。

因为操作需要支持分离与合并,因此我们用Splay来维护每一条Preferred Path。

各种操作

Access(x)

所谓access(x),即访问x节点。当x被访问后,x到根节点的路径就变成了Preferred Path。

给张图体会一下:
这里写图片描述

Access的实现非常暴力。假设当前节点为x,上一个节点为v(即x是v所在Preferred Path 的 Path Parent)。每次直接把x的Preferred Child。但是由于有Splay,我们就先把x Splay到根。如果x有右子树(即x的Preferred Child),那么就把x与它的右子树断开,接上v。x原来的右子树就重新建一颗树,其Path Parent为它自己。一直做到Preferred Path包含根节点为止。

MakeRoot(x)

让x成为树的根。

先Access(x),此时x与根节点就在同一颗平衡树上了。接着把x Splay到根,因为x必然是最深的点,所以Splay后所有的节点都在x的左边。此时只要交换x的左右子树,就可以把x变成树的根了。而这个操作可以同区间翻转一样打个Tag来实现。

Cut(x,y)

断开x和y。

先MakeRoot(x),再Access(y),此时x和y就在同一颗平衡树上了,且这棵树上只有x和y,根节点为y。再把y的左子树(x)和x的父亲(y)清零。

Link(x,

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值