[模板] 动态树/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 ...
随机推荐
- 调用EntityManagerFactory错误:The import javax.persistence cannot be resolved
缺少jar包:hibernate-jpa-2.0-api-1.0.0.Final.jar
- Django学习之一:Install Djongo 安装Djongo
Install Djongo 安装Djongo Djongo是基于python的web框架,自然安装最关心的是python解释器版本了. Prerequisites 安装条件 Python版本与Djo ...
- 《Pro Asp.net core mvc 2》bower问题
在阅读<Pro Asp.net core mvc 2>中有使用bower管理包,可能是由于vs2017或者bootstrap什么地方改变了,按照步骤进行操作,完全没有对应的样式出现.开始以 ...
- Mysql 数据库常用配置命令
1.查看mysql数据库默认编码: mysql> show variables like "character%"; +--------------------------+ ...
- ASP.NET Core 入门教程 9、ASP.NET Core 中间件(Middleware)入门
一.前言 1.本教程主要内容 ASP.NET Core 中间件介绍 通过自定义 ASP.NET Core 中间件实现请求验签 2.本教程环境信息 软件/环境 说明 操作系统 Windows 10 SD ...
- T-SQL_select语句详解
select语句执行的过程: 先看查询内容 ==>where条件 ==>[分组条件] ==>[分组搜索条件] ==>内容输出 ==>[是否排序] SQL中SELECT语句 ...
- 【原】Java学习笔记015 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 传递 值类型参数 ...
- springboot项目
https://my.oschina.net/ityouknow/blog/1629066
- HBase Client JAVA API
旧 的 HBase 接口逻辑与传统 JDBC 方式很不相同,新的接口与传统 JDBC 的逻辑更加相像,具有更加清晰的 Connection 管理方式. 同时,在旧的接口中,客户端何时将 Put 写到服 ...
- JS中的六大数据类型
js中有六种数据类型,包括五种基本数据类型(Number,String,Boolean,Undefined,Null),和一种复杂数据类型(Object). typeof 操作符 由于js中的变量是松 ...