[模板] 动态树/LCT
简介
LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证)
思想类似树链剖分, 因为splay可以换根, 用splay维护重链, splay的中序遍历即为链按深度从小到大遍历的结果.
操作
注意区分splay和整棵树的区别, splay根和树根的区别.
\(Access(p)\) 操作指的是将p与根放在同一棵splay中.
\(MakeRoot(p)\) 操作指的是将p变为它所在树(而不是splay)的根. 由于维护的是链上信息, 这不会对答案产生影响.
\(FindRoot(p)\) 操作指的是求p所在树(而不是splay)的根.
\(Link(x,y)\) 操作指的是如果p与q不在同一棵树中, 那么连边 \((x,y)\).
\(Cut(x,y)\) 操作指的是如果p与q有边相连, 那么连边 \((x,y)\).
其中, 'p与q有边相连' 等价于同时满足:
- p,q在同一棵树中.
- p,q深度相差1.(splay中p,q中序遍历时相邻)
\(Split(x,y)\) 操作指的是取出 \((x,y)\) 这个链, 并放在一棵splay中.
具体实现见代码.
应用
- 动态树(代替树链剖分)
- 动态最小生成树
- 维护子树信息(AAA树)
- 维护并查集(e.g. 可持久化并查集)
- 优化dinic(据tarjan论文)(怕不是会写死)
Code
const int nsz=3e5+50;
int n,val[nsz];
struct tlct{
struct tnd{int ch[2],fa,sum,rv;}tree[nsz];
#define ls(p) tree[p].ch[0]
#define rs(p) tree[p].ch[1]
#define fa(p) tree[p].fa
#define dir(p) (rs(fa(p))==p)
bool isrt(int p){return ls(fa(p))!=p&&rs(fa(p))!=p;}//splay rt
void rev(int p){swap(ls(p),rs(p));tree[p].rv^=1;}
void pu(int p){
tree[p].sum=tree[ls(p)].sum^val[p]^tree[rs(p)].sum;
}
void pd(int p){
if(tree[p].rv==0)return;
if(ls(p))rev(ls(p));
if(rs(p))rev(rs(p));
tree[p].rv=0;
}
void pdt(int p){//push down whole splay; from top to bottom
if(!isrt(p))pdt(fa(p));
pd(p);
}
void rotate(int p){//fa(p) should exist
int x=fa(p),y=fa(x),dir1=dir(p),dir2=dir(x),z=tree[p].ch[dir1^1];
if(!isrt(x))tree[y].ch[dir2]=p;fa(p)=y;
tree[p].ch[dir1^1]=x;fa(x)=p;
tree[x].ch[dir1]=z;if(z)fa(z)=x;
pu(x),pu(p);//can't swap
}
void splay(int p){
pdt(p);
while(!isrt(p)){
if(!isrt(fa(p)))rotate(dir(p)==dir(fa(p))?fa(p):p);
rotate(p);
}
}
void access(int p){
for(int y=0;p;y=p,p=fa(p)){
splay(p),rs(p)=y;
pu(p);
}
}
void makert(int p){//p -> tree rt & splay rt
access(p),splay(p);
rev(p);
}
int findrt(int p){//find tree rt; p -> splay rt
access(p),splay(p);
while(ls(p))pd(p),p=ls(p);
splay(p); //不加会tle... 不知道为什么
return p;
}
bool iscon(int x,int y){return findrt(x)==findrt(y);}
void split(int x,int y){//x -> tree rt; y -> splay rt
makert(x);
access(y);
splay(y);
}
void link(int x,int y){
makert(x);
if(findrt(y)!=x)fa(x)=y;
}
void cut(int x,int y){
split(x,y);
if(fa(x)==y&&rs(x)==0)
fa(x)=ls(y)=0,pu(y);
}
void pr(){
rep(i,1,n)printf("nd=%d fa=%d ls=%d rs=%d sum=%d rv=%d\n",i,fa(i),ls(i),rs(i),tree[i].sum,tree[i].rv);
}
}lct;
//init
rep(i,1,n)tree[i].sum=val[i];
//query a chain
lct.split(b,c);
ans=lct.tree[c].sum;
//modify one point
lct.makert(b);
val[b]=c;
lct.pu(b);
[模板] 动态树/LCT的更多相关文章
- hdu 5002 (动态树lct)
Tree Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- hdu 5398 动态树LCT
GCD Tree Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- bzoj2049-洞穴勘测(动态树lct模板题)
Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...
- 动态树LCT(Link-cut-tree)总结+模板题+各种题目
一.理解LCT的工作原理 先看一道例题: 让你维护一棵给定的树,需要支持下面两种操作: Change x val: 令x点的点权变为val Query x y: 计算x,y之间的唯一的最短路径的点 ...
- 动态树LCT小结
最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...
- SPOJ OTOCI 动态树 LCT
SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...
- HDU 4718 The LCIS on the Tree (动态树LCT)
The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Oth ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2843 Solved: 1519[Submi ...
- HDU 5002 Tree(动态树LCT)(2014 ACM/ICPC Asia Regional Anshan Online)
Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node ...
随机推荐
- 后端开发者的Vue学习之路(二)
目录 上篇内容回顾: 数据绑定 表单输入框绑定 单行文本输入框 多行文本输入框 复选框checkbox 单选框radio 选择框select 数据绑定的修饰符 .lazy .number .trim ...
- ios屏幕怎么投屏到电脑显示器
iphone在国内一直都很受欢迎,为什么这么受欢迎呢?其实苹果手机操作系统非常的新颖,让人对手机有了重新的认识.但是ios屏幕怎么投屏到电脑显示器.感兴趣的一起阅读下面的内容吧! 使用工具: 苹果手机 ...
- BGP:所有邻居都启动了BGP,则无须建立首尾逻辑邻居,否则就需要首尾建立逻辑邻居。
配置说明:都通过loopback 口作为bgp 连接口,并且要配置ebgp多跳,同时配置loopback口的静态路由. 以AR2为例: 第一种场景:所有直接相连的邻居都启动了BGP,则路由可以随意扩散 ...
- Android预置Apk方法
这一套8.0过时了 需要修改pms代码 否则apk会被pms删除掉 因为工作需要,经常要开发和合入系统App,所以在此开篇作为收集和记录Android合入系统应用的方法,以备日后查阅. 一.预置apk ...
- vue安装和使用
首先这里记录的是基于安装node.js 的npm安装vue 如果你不是用的node与npm 那就不必往下看了 1.安装node.js这个不多说 百度有很多 2.安装webpack 全局安装we ...
- ASP.NET Zero--解决方案结构(层)
解决方案结构(层) 创建和下载项目后,您将具有如下所示的解决方案结构: 解决方案有8个项目: Core项目包含域层类(如 实体 和 域服务). Application项目包含应用程序逻辑(如应用程序服 ...
- 【原】Java学习笔记013 - 阶段测试
package cn.temptation; import java.util.Scanner; public class Sample01 { public static void main(Str ...
- Win10 Service'MongoDB Server' failed to start. Verify that you have sufficient privileges to start system services【简记】
最近工作中有需要用到 MongoDB数据库,以前用的3.*的版本,这次用的是较新4.0.6的版本,然后去官网下载安装. 安装到一半,就弹出如下提示,说是"MongoDB Server&quo ...
- 构建高性能服务 Java高性能缓冲设计 vs Disruptor vs LinkedBlockingQueue
一个仅仅部署在4台服务器上的服务,每秒向Database写入数据超过100万行数据,每分钟产生超过1G的数据.而每台服务器(8核12G)上CPU占用不到100%,load不超过5.这是怎么做到呢?下面 ...
- [LeetCode] 6. Z 字形变换
题目链接:(https://leetcode-cn.com/problems/zigzag-conversion/) 题目描述: 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列 ...