bzoj 2049 [Sdoi2008]Cave 洞穴勘测(LCT)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=2049
【题意】
给定森林,可能有连边或断边的操作,回答若干个连通性的询问。
【思路】
Link-Cut-Tree。
LCT的性质:
1. 有一条重链上的所有节点构成的splay称作这条链的辅助树。
2. 每个点的键值为这个点的深度。
3. 链的辅助树的根的父亲指向链顶的父亲,然而链顶父亲的儿子并不指向链的辅助树的根。
(我会告诉你上面是抄的Popoqqq大爷的PPT么
LCT的操作:
Access:切断原来的重儿子,将结点到原树根的路径变为重路径。先splay到辅助树的根,然后修改右儿子,只用修改ch[1],右儿子的fa不用改变。
Evert:将u旋转至原树的根,因为执行完Access之后u只是辅助树的根,所以还需要splay至原树根。维护2性质,通过旋转之后u到根的路径反转,需要打上反转标记。
Link:连接两个不相连的节点。将u旋转至原树的根,然后将u的fa设为v。注意这里的操作并不是合并splay而只是连接两棵辅助树。
Cut:断开两个节点。将u旋转至跟,然后Access(v),splay(v),这时候u一定处于v的左子树,直接切断就行了。
【代码】
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
using namespace std; const int N = 1e5+; struct Node {
Node *ch[],*fa;
int rev;
Node() ;
void reverse() {
rev^=;
swap(ch[],ch[]);
}
void up_push() {
if(fa->ch[]==this||fa->ch[]==this)
fa->up_push();
if(rev) {
ch[]->reverse();
ch[]->reverse();
rev=;
}
}
void maintain() {
}
};
Node *null=new Node,T[N];
Node::Node() { fa=ch[]=ch[]=null; rev=; } void rot(Node* o,int d) { //将o点向上旋转,方向为d^1
Node *p=o->fa;
p->ch[d]=o->ch[d^];
o->ch[d^]->fa=p;
o->ch[d^]=p;
o->fa=p->fa;
if(p==p->fa->ch[])
p->fa->ch[]=o;
else if(p==p->fa->ch[])
p->fa->ch[]=o;
p->fa=o;
p->maintain();
}
void splay(Node* o) { //自下向上旋转至[所属splay]的根
o->up_push();
Node *nf,*nff;
while(o->fa->ch[]==o||o->fa->ch[]==o) { //判断是否是根
nf=o->fa,nff=nf->fa;
if(o==nf->ch[]) {
if(nf==nff->ch[]) rot(nf,);
rot(o,);
} else {
if(nf==nff->ch[]) rot(nf,);
rot(o,);
}
}
o->maintain();
}
void Access(Node* o) {
Node* son=null;
while(o!=null) { //将o到根的路径变为重路径即合并到一棵splay
splay(o);
o->ch[]=son;
o->maintain();
son=o; o=o->fa;
}
}
void evert(Node* o) { //将o转到[整棵动态树]的根
Access(o);
splay(o);
o->reverse();
}
void Link(Node* u,Node* v) {
evert(u);
u->fa=v; //辅助树的根指向链顶的父亲然而链顶的父亲并不指向根
}
void Cut(Node* u,Node* v) {
evert(u);
Access(v),splay(v);
v->ch[]=u->fa=null;
v->maintain();
} int n,m; void query(Node* u,Node* v)
{
Access(u),splay(u);
while(v->fa!=null) v=v->fa;
if(u==v) puts("Yes");
else puts("No");
} int main()
{
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
null->fa=null->ch[]=null->ch[]=null;
char op[]; int u,v;
scanf("%d%d",&n,&m);
while(m--) {
scanf("%s%d%d",&op,&u,&v);
if(op[]=='Q')
query(&T[u],&T[v]);
else if(op[]=='C')
Link(&T[u],&T[v]);
else
Cut(&T[u],&T[v]);
}
return ;
}
bzoj 2049 [Sdoi2008]Cave 洞穴勘测(LCT)的更多相关文章
- bzoj 2049: [Sdoi2008]Cave 洞穴勘测 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2049 题面: 2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 1 ...
- BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 LCT
2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...
- BZOJ 2049: [Sdoi2008]Cave 洞穴勘测——LCT
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2049 省选之前来切一道数据结构模板题. 题意 这是一道模板题. N个点,M次操作,每次加边/ ...
- BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 (LCT维护连通性)
直接把x设为根,然后查询y所在联通块的根是不是x就行了. CODE #include <cstdio> #include <cstring> #include <algo ...
- BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 (动态树入门)
2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1528 Solved: 644[Submit][ ...
- bzoj 2049: [Sdoi2008]Cave 洞穴勘测 动态树
2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 3119 Solved: 1399[Submit] ...
- [BZOJ 2049] [Sdoi2008] Cave 洞穴勘测 【LCT】
题目链接:BZOJ - 2049 题目分析 LCT的基本模型,包括 Link ,Cut 操作和判断两个点是否在同一棵树内. Link(x, y) : Make_Root(x); Splay(x); F ...
- 【刷题】BZOJ 2049 [Sdoi2008]Cave 洞穴勘测
Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...
- 【BZOJ】2049: [Sdoi2008]Cave 洞穴勘测 LCT
[题意]给定n个点和m个操作,每次操作:1.连接2个点.2.断开2个点.3.查询2个点是否连通.m<=2*10^5. [算法]Link-Cut Tree [题解]LCT模板题,Link,Cut, ...
随机推荐
- login.java
import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Login extends JFrame ...
- VCL源码分析方法论(以TButton.Caption属性的由来为例)
最近一段时间似乎流行源码分析:)我也来谈谈在过去一段时间里对VCL源码的分析方法方面的一点体会,本文将不探讨VCL类库的构架和设计模式方面的东本,只是以我们常见的控件属性/方法的实现过程作简单的说明, ...
- Maven Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean Failed to delete access_log
I'm trying to run simple struts project using maven and tomcat. When I'm trying to exucute next goal ...
- Android 时间轴TimeLine
代码:这里
- Android开发之消息机制
转:http://stackvoid.com/introduction-to-Message-Handler-in-Android/ http://blog.dreamtobe.cn/2016/03/ ...
- 查看mssql死锁的详细信息(存储过程)
CREATE procedure [dbo].[sp_who_lock]asbegindeclare @spid int,@bl int, @intTransactionCountOn ...
- Android手机拍照
参考的这个视频教程:http://v.youku.com/v_show/id_XNjI5MzkzMjQ4.html和官方API档file:///D:/Android/androidstudio/sdk ...
- 面试题_31_to_47_JVM 底层与GC(Garbage Collection)的面试问题
31)64 位 JVM 中,int 的长度是多数?Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位.意思就是说,在 32 位 和 64 位 的Java 虚拟机中,int 类 ...
- eclipse mingw cpp开发环境
Eclipse开发c++ 对比:微软的VC++6.0:太老了,对win7兼容不好, 现在微软的Visual Studio:安装包太大,好几个G,装了一堆你不需要的东西,要钱,教 育版申请麻烦 DOS下 ...
- IIS Web负载均衡的几种方式
Web负载均衡的几种实现方式 摘要:负载均衡(Load Balance)是集群技术(Cluster)的一种应用.负载均衡可以将工作任务分摊到多个处理单元,从而提高并发处理能力.目前最常见的负载均衡应用 ...