介绍一下动态树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的判断(父节点为空或为虚边)。

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

相关推荐
NiceCloud喜云2 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
小羊在睡觉2 小时前
力扣84. 柱状图中最大的矩形
后端·算法·leetcode·golang·go
3DVisionary2 小时前
蓝光三维扫描:医疗制造的精度焦虑怎么解
人工智能·算法·制造·蓝光三维扫描·医疗制造·三维检测·义齿检测
AI玫瑰助手2 小时前
Python函数:默认参数的定义与注意事项
开发语言·python·信息可视化
好评笔记2 小时前
机器学习面试八股——常用损失函数
人工智能·深度学习·算法·机器学习·校招
weixin_468466852 小时前
全局与局部注意力机制新手实战指南
人工智能·python·深度学习·算法·自然语言处理·transformer·注意力机制
油炸自行车2 小时前
Claude Code 错误:API Error: 400 Failed to deserialize the JSON body into the
开发语言·javascript·json·trae·claude code·api error 400
肩上风骋2 小时前
C++14特性
开发语言·c++·c++14特性
小糖学代码3 小时前
LLM系列:环境搭建:5.Python-dotenv 环境变量管理
人工智能·python·深度学习·神经网络
_日拱一卒3 小时前
LeetCode:994腐烂的橘子
java·数据结构·算法·leetcode·深度优先