[SDOI2008] 洞穴勘测 (LCT模板)
Link-Cut Tree的基本思路是用splay的森林维护一条条树链。
splay的森林,顾名思义,就是若干splay组成的东西。
每个splay都有一个根节点,所以lct里的splay不能记录根节点,因为根节点有好多。
我们开一个bool数组记录每个点是否为根节点。
每个splay都维护一条重链,重链之间的轻链在splay里只从儿子指向父亲,而父亲并没有这个儿子。

就像图里的红箭头。
每个splay都表示一条重链,这个splay的中序遍历与链上节点的深度顺序是一致的。
接下来是splay里最重要的操作:access(p)
就是指打通从p到整棵树的树根的一条重链。
同时也把p下面接的链变成轻链。

之后还有一个操作:move_to_root,把p变成整棵树的根。
在access之后,p和树根之间是重链直接连接,而一个splay维护一个重链,所以此时p和根已经在一个splay里了。
我们只需要splay(p)即可。
但是这样的话破坏了深度的性质。
把左右反转一下就行了:reverse(p)
接下来就是link和cut的操作。
link(x,y)很简单,mtr(x),之后接一条从x到y的轻链即可。
cut(x,y)的话,mtr(x),access(y),splay(y),x就是y的左儿子了。删掉父子关系即可。
查询连通性:mtr(x),access(y),splay(y),x就在y的子树里了。x=f[x]一直往上跳,判断最后y的终点是不是x。
这些大概是最最基础的操作了,子树信息什么的都不用维护。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define id(x) (s[f[x]][1]==x)
using namespace std; int n,m;
int f[],s[][];
bool rev[],rt[]; void reverse(int p)
{
swap(s[p][],s[p][]);
rev[p]^=;
} void pushdown(int p)
{
if(!rev[p])return;
reverse(s[p][]);
reverse(s[p][]);
rev[p]=;
} void down(int p)
{
if(!rt[p])down(f[p]);
pushdown(p);
} void rotate(int p)
{
int k=id(p);
int fa=f[p];
if(rt[fa])rt[p]=,rt[fa]=;
else s[f[fa]][id(fa)]=p;
s[fa][k]=s[p][!k];
s[p][!k]=fa;
f[p]=f[fa];
f[fa]=p;
f[s[fa][k]]=fa;
} void splay(int p)
{
down(p);
while(!rt[p])
{
int fa=f[p];
if(rt[fa])
{
rotate(p);
return;
}
if(id(p)^id(fa))rotate(p);
else rotate(fa);
rotate(p);
}
} void access(int p)
{
int son=;
while(p)
{
splay(p);
rt[s[p][]]=,rt[son]=;
s[p][]=son;
son=p,p=f[p];
}
} void mtr(int p)
{
access(p);
splay(p);
reverse(p);
} void link(int x,int y)
{
mtr(x);
f[x]=y;
} void cut(int x,int y)
{
mtr(x);
access(y);
splay(y);
s[y][]=f[x]=;
rt[x]=;
} void check(int x,int y)
{
mtr(x);
access(y);
splay(y);
while(!rt[x])x=f[x];
printf("%s\n",(x==y?"Yes":"No"));
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)rt[i]=;
char op[];
int x,y;
while(m--)
{
scanf("%s",op+);
scanf("%d%d",&x,&y);
if(op[]=='C')link(x,y);
if(op[]=='D')cut(x,y);
if(op[]=='Q')check(x,y);
}
return ;
}
[SDOI2008] 洞穴勘测 (LCT模板)的更多相关文章
- [BZOJ2049][Sdoi2008]Cave 洞穴勘测 LCT模板
2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 9705 Solved: 4674[Submit] ...
- BZOJ2049[Sdoi2008]洞穴勘测——LCT
题目描述 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如 ...
- 洛谷P2147[SDOI2008]洞穴勘测(lct)
题目描述 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假 ...
- [LuoguP2147] [SDOI2008]洞穴勘测 (LCT维护连通性)
题面 传送门:https://www.luogu.org/problemnew/show/P2147 Solution 这题...... 我们可以发现题目要求我们维护一个动态森林,而且只查询连通性.. ...
- BZOJ 2049 SDOI2008 洞穴勘测 LCT板子
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2049 题意概述:给出N个点,一开始不连通,M次操作,删边加边,保证图是一个森林,询问两点连 ...
- BZOJ 2049 [SDOI2008]洞穴勘测 (LCT)
题目大意:维护一个森林,支持边的断,连,以及查询连通性 LCT裸题 洛谷P2147传送门 1A了,给自己鼓鼓掌 #include <cstdio> #include <algorit ...
- 洛谷 P2147 [SDOI2008]洞穴勘测 LCT
Code: #include <cstdio> #include <algorithm> #include <string> #include <cstrin ...
- P2147 [SDOI2008]洞穴勘测(LCT)
P2147 [SDOI2008]洞穴勘测 裸的LCT. #include<iostream> #include<cstdio> #include<cstring> ...
- P2147 [SDOI2008]洞穴勘测
P2147 [SDOI2008]洞穴勘测 思路 没办法,我就是喜欢板子都想发的人 都是基础操作,不多说了 代码 #include <bits/stdc++.h> #define ls ch ...
随机推荐
- 使用Eclipse开发学习 Spring Boot 教程的内容小结
spring-tool-suite使用教程,并创建spring配置文件 Spring Boot基础教程1-Spring Tool Suite工具的安装 Spring Boot基础教程2-RESTful ...
- sklearn连续型数据离散化
二值化 设置一个condition,把连续型的数据分类两类.比如Age,大于30,和小于30. from sklearn.preprocessing import Binerize as Ber x ...
- 微信小程序使用第三方FontIcon库的部分字体图标
一.提取部分图标重新制作TTF字库 我没有使用网上大多数文章写的淘宝提供的fonticon,而只使用了Ionicons的几个图标,所以打开Ionicons的官网点击右上角的Designer pack下 ...
- 2019牛客暑期多校训练营(第五场)B.generator 1
传送门:https://ac.nowcoder.com/acm/contest/885/B 题意:给出,由公式 求出 思路:没学过矩阵快速幂.题解说是矩阵快速幂,之后就学了一遍.(可以先去学一下矩阵快 ...
- ansible-playbook编写服务器初始化脚本
1.原理:通过limit的参数,限制新定义的服务器.即可给新买的服务器初始化优化.(如下图所示) 首先我们编写一个总入口的palybook脚本: init.yml --- - hosts: all u ...
- http跳转http
server {listen 80;server_name 123.com;root /var/www/web/123;index index.html index.htm index.php;rew ...
- AUTOSAR 架构
AUTOSAR 软件架构 1.AUTOSAR 软件 2.AUTOSAR 运行时环境(RTE) 3.AUTOSAR 基本软件 (BSW) 1.服务:诊断协议等系统服务及NVRAM管理 2.通信:CAN. ...
- Docker系列五: docker-compose部署Docker容器
Docker使用Dockerfile来实现对现有镜像的修改来创建新的镜像, 那docker-compose则完成镜像的自动部署, 可以实现多个容器同时部署 Dockerfile可以让用户管理一个单独的 ...
- Linux基本操作_20191117
VMware和Ubuntu的安装, 想来想去,还是需要安装,不能老是使用Windows的,后面还有很多都要用到Linux系统的,这个可以说是开发人员必备的了, 基本的使用: 1,Windows下面C: ...
- 定义变量|dirname|basename|printf
$ basename /xxxx/test test $ dirname /xxxx/test /xxx $ dirname /xxx/test|while read p;do sp=$p" ...