[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 ...
随机推荐
- PAT Advanced 1081 Rational Sum (20) [数学问题-分数的四则运算]
题目 Given N rational numbers in the form "numerator/denominator", you are supposed to calcu ...
- Qt QRect与QRectF的区别
一直在与QRect和QRectF打交道.甚至在使用过程中因为QRect而出现了致命的Bug.因为QRect在数据存储表示上有一个很大的“历史遗留问题”! QRect Class 也就是说,对于QR ...
- Java之同步方法处理实现Runnable接口的线程安全问题
/** * 使用同步方法解决实现Runnable接口的线程安全问题 * * * 关于同步方法的总结: * 1. 同步方法仍然涉及到同步监视器,只是不需要我们显式的声明. * 2. 非静态的同步方法,同 ...
- 如何编写一个vue应用
1.vue应用的组成 1.1 vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 通常 ...
- VS Code之Vue开发常用插件
Auto Close Tag 自动补全html标签 Auto Rename Tag 同步更改html尾标签 ESLint ESlint语法提示 settings.json 文件 "eslin ...
- Tarjan算法:求解无向连通图图的割点(关节点)与桥(割边)
1. 割点与连通度 在无向连通图中,删除一个顶点v及其相连的边后,原图从一个连通分量变成了两个或多个连通分量,则称顶点v为割点,同时也称关节点(Articulation Point).一个没有关节点的 ...
- web开发相关工具总结
系统: linux -ssh工具:secureCRT ,PUTTY,XSHELL MYSQl: mysql客户端 ,mysqlworkbench, navicat for mysql ,phpmyad ...
- @ResponseBody与@RestController
@ResponseBody与@RestController的作用与区别 https://blog.csdn.net/xfl4629712/article/details/78528387
- Android 自定义dialog类
首先定制style样式 styles.xml 加入自定义样式 <style name="CustomLoadingDialog"> <item name=&quo ...
- Mac中Apache常用命令
Apache常用命令记录,还是记一下吧,总是忘记. Apache常用命令: # sudo apachectl start // 启动Apache服务 # sudo apachectl stop // ...