一棵link/cut tree是一种用以表示一个森林,一个有根树集合的数据结构。它提供以下操作:

  • 向森林中加入一棵只有一个点的树。
  • 将一个点及其子树从其所在的树上断开。
  • 将一个点连接至另一个顶点,作为其子节点。
  • 求出一个点所在树的根。通过对两个不同的点进行此操作,我们可以判断他们是否属于同一棵树。

    翻译自Link/cut tree - Wikipedia,英语好的小伙伴看这个就很不错

在link/cut tree中,边分为两种:偏爱边(preferred edges)和普通边(normal edges),每个非叶节点都有一条偏爱边指向其偏爱子节点(preferred child)。偏爱边形成的路径称为偏爱路径(preferred paths)

实际上,link/cut tree是将森林划分为若干条链(也就是偏爱路径),并用以深度作为splay去分别维护每一条链。这些splay被称为辅助树(auxiliary tree)。操作时不要考虑splay的结构,只要考虑原树的结构就好。

link/cut tree主要支持四种操作makeRt(p)cut(p)link(p,q)path(p,q),而这些操作都是基于access(p)的。下面分别介绍如何实现这些操作。

Access

void access(int p) {for(int q=0;p;q=p,p=fa[p]) splay(p),ch[p][1]=q,update(p);}

首先当然要介绍作为万恶之源的access(p)access(p)的效果是将\(p\)与其所在树的根置于一条链上,并且\(p\)是这条链的末尾。可以看一下wiki的这张图:

左边是access(l)前,中间是access(l)后,右边是在splay上的实际操作。



实际操作中,我们要断掉\(p\)下面的点,并将\(p\)所在链连接到它上面的一个点\(t\)上,然后断掉\(t\)下面的点。大概是这样:



每经过一次这样的操作,\(p\)就会连接到上一层的链上。反复操作直到\(p\)与\(rt\)相连。

在辅助树中,断掉\(p\)下面的点相当于splay(p)并改变ch[p][1]。\(q\)记录应该将谁接在\(t\)下面,也就是上一次的\(p\)啦。

MakeRt

void makeRt(int p) {access(p); splay(p),rever(p);}

rever(p)表示翻转splay中的\(p\)。当我们access(p)后,\(p\)成为了其所在链上最深的点,那么splay(p)后\(p\)就只有左子树。翻转\(p\)就把\(p\)变成了链上最浅的点,也就是根啦。

这段细节上我也想不太明白...别的点怎么啦?每条链都没有变化(只是存储链的splay结构变化了),链之间的连接也没有变化,那么原树的结构就不会变化。

Cut

void cut(int p) {access(p); splay(p),fa[ch[p][0]]=0,ch[p][0]=0; update(p);}

断掉\(p\)上面的点,也就是断掉与ch[p][0]的连接。

Link

void link(int p,int q) {makeRt(p); fa[p]=q;}

如果\(p\)是一棵树的根的话,直接将\(p\)接在\(q\)下面就可以了。

Path

void path(int p,int q) {makeRt(p),access(q),splay(q);}

将\(p\)变为根,再把\(q\)和根(也就是\(p\))置于同一链上。这样就形成了一个只维护\((p,q)\)这条链的辅助树,然后就可以为所欲为啦。

Link/cut Tree的更多相关文章

  1. link cut tree 入门

    鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...

  2. Codeforces Round #339 (Div. 2) A. Link/Cut Tree 水题

    A. Link/Cut Tree 题目连接: http://www.codeforces.com/contest/614/problem/A Description Programmer Rostis ...

  3. 洛谷P3690 Link Cut Tree (模板)

    Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...

  4. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  5. bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门

    link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...

  6. P3690 【模板】Link Cut Tree (动态树)

    P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...

  7. Link Cut Tree学习笔记

    从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...

  8. [CodeForces - 614A] A - Link/Cut Tree

    A - Link/Cut Tree Programmer Rostislav got seriously interested in the Link/Cut Tree data structure, ...

  9. Link Cut Tree 总结

    Link-Cut-Tree Tags:数据结构 ##更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1027479 一.概述 \(LCT\),动态树的一种,又可以 ...

随机推荐

  1. C# 类型基础(下)

    前面介绍了基本的类型,接下来我们讲讲类型的转换 值类型的两种表现形式:未装箱和已装箱 ,而引用类型总是处于装箱形式 int count = 10; object obj = count; 装箱:值类型 ...

  2. mybatis支持oracle批量插入

    问题:mysql使用mybatis批量插入时,通过foreach标签,将每条记录按照逗号","连接即可. 但是,oracle不支持. oracle支持如下写法: <inser ...

  3. 查询集API -- Django从入门到精通系列教程

    该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. Python及Django学习QQ群:453 ...

  4. C#基础(二)--之数据类型

    在第一章我们了解了C#的输入.输出语句后,我这一节主要是介绍C#的基础知识,本节的内容也是后续章节的基础,好的开端等于成功的一半.在你阅读完本章后,你就有足够的C#知识编写简单的程序了.但还不能使用继 ...

  5. Numpy基础学习

    Numpy(Numerical Python的简称)是高性能科学计算和数据分析的基础包. 主要的功能: 1.ndarray,一个具有矢量运算和复杂广播工能的快速且节省空间的多维数组 2.用于对整组数据 ...

  6. 百度地图api 区级以下行政区划

    我们在使用百度地图api想要展示苏州市吴中区各乡镇的行政区范围: 百度api有提供了“添加行政区划”的示例:http://lbsyun.baidu.com/jsdemo.htm#c1_10 但该功能目 ...

  7. CLR via C#读书日记一' 引用类型和值类型'

    CLR支持两种类型:引用类型和值类型. 引用类型总是在托管堆上分配的,C#的new操作符会返回对象的内存地址——也就是指向对象数据的内存地址. 使用引用类型必须注意到一些问题: 1)内存必须从托管堆上 ...

  8. C# 使用 Lotus notes 公共邮箱发送邮件

    公司的邮件系统用的是反人类的 Lotus notes, 你敢信? 最近要实现一个功能,邮件提醒功能,就是通过自动发送提醒邮件 前前后后这个问题搞了2天,由于公司的诸多条件限制,无法直接调用到公司发送邮 ...

  9. 乞丐版servlet容器第1篇

    本系列参照pkpk1234大神的BeggarServletContainer,具体请访问:https://github.com/pkpk1234/BeggarServletContainer. 一步一 ...

  10. SynchronousQueue 的联想

    SynchronousQueue介绍 SynchronousQueue是一种阻塞队列,该队列没有任务的容量.内部实现采用了一种性能更好的无锁算法. 代码实现里的Dual Queue,其中每一个put对 ...