模板汇总——LCT
link-cut tree
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
const int N = 5e5 + ;
struct Node{
int rev, rt;
int son[], pre;
int mx, val, id;
void init(){
rt = ; rev = pre = son[] = son[] = ;
mx = val = id = ;
}
}tr[N];
void Push_Rev(int x){
if(!x) return ;
swap(lch(x), rch(x));
tr[x].rev ^= ;
}
void Push_Up(int x){
if(!x) return ;
tr[x].mx = tr[x].val, tr[x].id = x;
if(tr[x].mx < tr[lch(x)].mx) tr[x].mx = tr[lch(x)].mx, tr[x].id = tr[lch(x)].id;
if(tr[x].mx < tr[rch(x)].mx) tr[x].mx = tr[rch(x)].mx, tr[x].id = tr[rch(x)].id;
}
void Push_Down(int x){
if(tr[x].rev){
tr[x].rev = ;
Push_Rev(lch(x));
Push_Rev(rch(x));
}
}
void Rev(int x){
if(!tr[x].rt) Rev(tr[x].pre);
Push_Down(x);
}
void rotate(int x){
if(tr[x].rt) return;
int y = tr[x].pre, z = tr[y].pre;
int k = (rch(y) == x);
tr[y].son[k] = tr[x].son[k^];
tr[tr[y].son[k]].pre = y;
tr[x].son[k^] = y;
tr[y].pre = x;
tr[x].pre = z;
if(tr[y].rt) tr[y].rt = , tr[x].rt = ;
else tr[z].son[rch(z) == y] = x;
Push_Up(y);
}
void Splay(int x){
Rev(x);
while(!tr[x].rt){
int y = tr[x].pre, z = tr[y].pre;
if(!tr[y].rt){
if(( x == rch(y) ) != (y == rch(z))) rotate(x);
else rotate(y);
}
rotate(x);
}
Push_Up(x);
}
void Access(int x){
int y = ;
do{
Splay(x);
tr[rch(x)].rt = ;
rch(x) = y;
tr[y].rt = ;
Push_Up(x);
y = x;
x = tr[x].pre;
}while(x);
}
void Make_rt(int x){
Access(x);
Splay(x);
Push_Rev(x);
}
bool judge(int u, int v){
while(tr[u].pre) u = tr[u].pre;
while(tr[v].pre) v = tr[v].pre;
return u == v;
}
void link(int u, int v){
Make_rt(u);
tr[u].pre = v;
}
void cut(int u, int v){
Make_rt(u);
Access(v);
Splay(v);
tr[lch(v)].pre = ;
tr[lch(v)].rt = ;
tr[v].pre = ;
lch(v) = ;
}
维护子树。
维护子树就是新开一个状态存一下 所有非偏爱子节点的信息, 然后每次access的时候我们就根据偏爱子节点的变化, 从而更新这个新开的状态。
这个写法 是维护 子树内的亦或和。
代码:
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
const int N = 5e5 + ;
struct Node{
int rev, rt;
int son[], pre;
int sum, vsum, key;
void init(){
rt = ; rev = pre = son[] = son[] = ;
sum = vsum = key = ;
}
}tr[N];
void Push_Rev(int x){
if(!x) return ;
swap(lch(x), rch(x));
tr[x].rev ^= ;
}
void Push_Up(int x){
if(!x) return ;
tr[x].sum = tr[x].key ^ tr[lch(x)].sum ^ tr[rch(x)].sum ^ tr[x].vsum;
}
void Push_Down(int x){
if(tr[x].rev){
tr[x].rev = ;
Push_Rev(lch(x));
Push_Rev(rch(x));
}
}
void Rev(int x){
if(!tr[x].rt) Rev(tr[x].pre);
Push_Down(x);
}
void rotate(int x){
if(tr[x].rt) return;
int y = tr[x].pre, z = tr[y].pre;
int k = (rch(y) == x);
tr[y].son[k] = tr[x].son[k^];
tr[tr[y].son[k]].pre = y;
tr[x].son[k^] = y;
tr[y].pre = x;
tr[x].pre = z;
if(tr[y].rt) tr[y].rt = , tr[x].rt = ;
else tr[z].son[rch(z) == y] = x;
Push_Up(y);
}
void Splay(int x){
Rev(x);
while(!tr[x].rt){
int y = tr[x].pre, z = tr[y].pre;
if(!tr[y].rt){
if(( x == rch(y) ) != (y == rch(z))) rotate(x);
else rotate(y);
}
rotate(x);
}
Push_Up(x);
}
void Access(int x){
int y = ;
do{
Splay(x);
tr[rch(x)].rt = ;
tr[x].vsum ^= tr[rch(x)].sum;
rch(x) = y;
tr[x].vsum ^= tr[rch(x)].sum;
tr[y].rt = ;
Push_Up(x);
y = x;
x = tr[x].pre;
}while(x);
}
void Make_rt(int x){
Access(x);
Splay(x);
Push_Rev(x);
}
void link(int u, int v){
Make_rt(u);
Access(v);
Splay(v);
tr[u].pre = v;
tr[v].
vsum ^= tr[u].sum;
Push_Up(v);
}
void cut(int u, int v){
Make_rt(u);
Access(v);
Splay(v);
tr[lch(v)].pre = ;
tr[lch(v)].rt = ;
tr[v].pre = ;
lch(v) = ;
Push_Up(v);
}
模板汇总——LCT的更多相关文章
- 模板—数据结构—LCT
模板—数据结构—LCT Code: #include <cstdio> #include <algorithm> using namespace std; #define N ...
- 单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板
一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的 ...
- link cut tree模板(LCT模板)
update:2017.09.26 #include <bits/stdc++.h> using namespace std; struct Link_Cut_Tree { + ; ], ...
- 【模板】NOIP模板汇总
图论 数据结构 数学 其他: 洛谷模板:a,b两个字符串,求b串在a串中出现的位置 #include<iostream> #include<cstdio> #include&l ...
- 模板汇总——KMP & EX-KMP
1. kmp 相当于往前求出一段字符信息,使得 这段字符信息和前缀相等. void getnext(){ , j = ; nx[] = -; while(j < m){ || b[j] == b ...
- 模板汇总——AC自动机
AC自动机 模板题 HDU-2222 Keywords Search #include<bits/stdc++.h> using namespace std; #define LL lon ...
- 【模板】LCT
核心思想: 动态维护一个森林.支持删边,加边,查询链信息等很多操作. 由若干棵$Splay$组成,每棵$Splay$维护一条链,以深度作为关键字. 也就是说$Splay$的中序遍历相当于从上到下遍历这 ...
- python实现AES/DES/RSA/MD5/SM2/SM4/3DES加密算法模板汇总
都是作者累积的,且看其珍惜,大家可以尽量可以保存一下,如果转载请写好出处https://www.cnblogs.com/pythonywy 一.md5加密 1.简介 这是一种使用非常广泛的加密方式,不 ...
- 【POJ各种模板汇总】(写在逆风省选前)(不断更新中)
1.POJ1258 水水的prim……不过poj上硬是没过,wikioi上的原题却过了 #include<cstring> #include<algorithm> #inclu ...
随机推荐
- java多线程核心api以及相关概念(一)
这篇博客总结了对线程核心api以及相关概念的学习,黑体字可以理解为重点,其他的都是我对它的理解 个人认为这些是学习java多线程的基础,不理解熟悉这些,后面的也不可能学好滴 目录 1.什么是线程以及优 ...
- Ubuntu 执行chmod -R 777 / 挽救方法
mgj怎么会有堪比rm -rf /*这样神奇的命令,本想着把当前目录下的权限改为777,没想到把整个/目录下全设成777了,直觉告诉我好像哪里有些不对劲,好在一顿xjb折腾最终弄好了,应该没啥大问题, ...
- 一个项目的SpringCloud微服务改造过程
SSO是公司一个已经存在了若干年的项目,后端采用SpringMVC.MyBatis,数据库使用MySQL,前端展示使用Freemark.今年,我们对该项目进行了一次革命性的改进,改造成SpringCl ...
- 关于 java中的换行符
java中实现换行有以下3种方法: 1.使用java中的转义符"\r\n": String str="aaa"; str+="\r\n"; ...
- charles(version4.2.1)抓包手机数据
点击菜单栏的Proxy项,选择Proxy Settings. 设置HTTP Proxy的Port. 勾选透明代理Enable transparent HTTP proxying,也可不勾选. 设置代理 ...
- 每个程序员都可以「懂」一点 Linux
提到 Linux,作为程序员来说一定都不陌生.但如果说到「懂」Linux,可能就没有那么多人有把握了.到底用 Linux 离懂 Linux 有多远?如果决定学习 Linux,应该怎么开始?要学到什么程 ...
- python编写环境(种类)
python编写环境(种类) 官方推荐 cpython 转成C的字节码 jython转成Java的字节码 ironpython转成C#字节码 pypy转换成动态编译 开发快,运行快
- Java——反射:运行时的类信息
RTTI的使用 如果不知道某个对象的确切类型,RTTI会告诉我们,但是有一个限制:这个类型在编译时必须已知,这样才能使用RTTI识别它,并利用这些信息做一些有用的事情. 2.什么情况下需要反射 假设 ...
- python 列表的增删改查
列表 有序可变的,索引 作用:存储数据的,支持很多种数据类型 定义方式: lst = [1,"alex",True,('a','b')]增 append() # 追加 extend ...
- 夯实Java基础(十七)——注解(Annotation)
1.注解概述 从JDK5.0开始,Java增加对元数据(MetaData)的支持,也就是注解(Annotation).其实我们早就已经接触过注解了,例如我们经常在Java代码中可以看到 “@Overr ...