介绍一下动态树LCT(Python)

动态树(LCT)概述

动态树(Link-Cut Tree,LCT)是一种用于维护动态森林数据结构的高效算法,支持以下操作:

  • 动态连接与断开:在树之间添加或删除边。
  • 路径查询与修改:对树上两点间的路径进行信息统计(如最大值、求和)或批量修改。
  • 子树操作:部分变种支持子树查询。

LCT的核心思想是通过**伸展树(Splay Tree)**维护树的虚实链剖分,将操作复杂度均摊到 O(\\log n)


LCT的核心操作

数据结构定义

每个节点存储以下信息:

python 复制代码
class LCTNode:
    def __init__(self, val):
        self.val = val          # 节点值
        self.left = None       # 左孩子
        self.right = None      # 右孩子
        self.parent = None     # 父节点
        self.rev = False       # 翻转标记(用于路径反转)
        self.size = 1          # 子树大小(可选,用于维护附加信息)
基本Splay操作

Splay操作将节点旋转到当前伸展树的根,同时维护树的平衡:

python 复制代码
def splay(x):
    while not is_root(x):
        y = x.parent
        if not is_root(y):
            push_down(y.parent)  # 下传延迟标记
        push_down(y)
        push_down(x)
        if not is_root(y):
            if (y.parent.left == y) == (y.left == x):
                rotate(y)  # 同方向先转父节点
            else:
                rotate(x)
        rotate(x)
    update(x)  # 更新节点信息
虚实链切换

access(x) 操作将根到 x 的路径变为实链,其他边变为虚边:

python 复制代码
def access(x):
    last = None
    while x:
        splay(x)
        x.right = last  # 将原有右子树变为虚边
        update(x)       # 更新节点信息
        last = x
        x = x.parent
路径反转

make_root(x) 通过反转路径将 x 设为根:

python 复制代码
def make_root(x):
    access(x)
    splay(x)
    x.rev ^= True      # 打翻转标记
    swap(x.left, x.right)  # 实际翻转在push_down时处理

常用操作实现

连接两棵树(Link)

要求 xy 不在同一棵树中:

python 复制代码
def link(x, y):
    make_root(x)
    x.parent = y  # 将x作为y的虚儿子
断开边(Cut)

要求 xy 直接相连:

python 复制代码
def cut(x, y):
    make_root(x)
    access(y)
    splay(y)
    y.left.parent = None  # 断开x与y的边
    y.left = None
    update(y)
路径查询

查询 xy 的路径信息(如求和):

python 复制代码
def query_path(x, y):
    make_root(x)
    access(y)
    splay(y)
    return y.sum  # 假设维护了sum字段

复杂度分析

  • 单次操作:均摊 O(\\log n),依赖Splay树的均摊性质。
  • 空间O(n),每个节点需存储额外字段。

Python实现注意事项

  1. 延迟标记处理 :翻转标记(rev)需在Splay操作前下传。
  2. 维护附加信息 :如路径求和、最大值等,需在update函数中同步。
  3. 边界条件 :注意is_root的判断(父节点为空或为虚边)。

完整实现需结合具体问题调整,上述代码为简化版框架。

相关推荐
不穿铠甲的穿山甲1 小时前
MMR最大边际相关性
算法
handler011 小时前
速通蓝桥杯省一:二分算法
c语言·开发语言·c++·笔记·算法·职场和发展·蓝桥杯
炽烈小老头1 小时前
【 每天学习一点算法 2026/05/08】最小覆盖子串
学习·算法
lbb 小魔仙1 小时前
DolphinDB:以“存算一体“重新定义工业时序数据的边界
开发语言·人工智能·python·langchain·jenkins
callJJ1 小时前
Codex 联动 OpenSpec 提效方法论
java·开发语言·codex·openspec
上弦月-编程1 小时前
Java编程:跨平台开发利器
java·开发语言
IT策士1 小时前
Python Word操作:从入门到精通
python·c#·word
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第38题:两个对象的hashCode()相同,则 equals()是否也一定为 true?
java·开发语言·后端·面试·hash-index
java1234_小锋2 小时前
什么是可重入锁ReentrantLock?
java·开发语言