洛谷P2147 [SDOI2008] 洞穴勘探 [LCT]
洞穴勘探
题目描述
辉辉热衷于洞穴勘测。
某天,他按照地图来到了一片被标记为JSZX的洞穴群地区。经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴。假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径。 洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通道,有时这条通道又会因为某种稀奇古怪的原因被毁。
辉辉有一台监测仪器可以实时将通道的每一次改变状况在辉辉手边的终端机上显示:
如果监测到洞穴u和洞穴v之间出现了一条通道,终端机上会显示一条指令 Connect u v
如果监测到洞穴u和洞穴v之间的通道被毁,终端机上会显示一条指令 Destroy u v
经过长期的艰苦卓绝的手工推算,辉辉发现一个奇怪的现象:无论通道怎么改变,任意时刻任意两个洞穴之间至多只有一条路径。
因而,辉辉坚信这是由于某种本质规律的支配导致的。因而,辉辉更加夜以继日地坚守在终端机之前,试图通过通道的改变情况来研究这条本质规律。 然而,终于有一天,辉辉在堆积成山的演算纸中崩溃了……他把终端机往地面一砸(终端机也足够坚固无法破坏),转而求助于你,说道:“你老兄把这程序写写吧”。
辉辉希望能随时通过终端机发出指令 Query u v,向监测仪询问此时洞穴u和洞穴v是否连通。现在你要为他编写程序回答每一次询问。 已知在第一条指令显示之前,JSZX洞穴群中没有任何通道存在。
输入输出格式
输入格式:
第一行为两个正整数n和m,分别表示洞穴的个数和终端机上出现过的指令的个数。
以下m行,依次表示终端机上出现的各条指令。每行开头是一个表示指令种类的字符串s("Connect”、”Destroy”或者”Query”,区分大小写),之后有两个整数u和v
(1≤u, v≤n且u≠v) 分别表示两个洞穴的编号。
输出格式:
对每个Query指令,输出洞穴u和洞穴v是否互相连通:是输出”Yes”,否则输出”No”。(不含双引号)
输入输出样例
200 5
Query 123 127
Connect 123 127
Query 123 127
Destroy 127 123
Query 123 127
No
Yes
No
3 5
Connect 1 2
Connect 3 1
Query 2 3
Destroy 1 3
Query 2 3
Yes
No
说明
数据说明
10%的数据满足n≤1000, m≤20000
20%的数据满足n≤2000, m≤40000
30%的数据满足n≤3000, m≤60000
40%的数据满足n≤4000, m≤80000
50%的数据满足n≤5000, m≤100000
60%的数据满足n≤6000, m≤120000
70%的数据满足n≤7000, m≤140000
80%的数据满足n≤8000, m≤160000
90%的数据满足n≤9000, m≤180000
100%的数据满足n≤10000, m≤200000
保证所有Destroy指令将摧毁的是一条存在的通道
本题输入、输出规模比较大,建议c\c++选手使用scanf和printf进行I\O操作以免超时
分析:
那这道题来练练LCT。
完全是LCT的板子,三种操作分别对应$link$,$cut$,$findroot$。就这样。
感觉我还没有把LCT理解透彻,做LCT的题目还是不够熟练,还是得多练才行。
Code:
//It is made by HolseLee on 2nd Oct 2018
//Luogu.org P2147
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; const int N=1e4+;
int n,m; struct LCT {
int fa[N],ch[N][],sign[N],q[N],top; void ready()
{
memset(fa,,sizeof(fa));
memset(ch,,sizeof(ch));
memset(sign,,sizeof(sign));
memset(q,,sizeof(q));
top=;
} inline void pushr(int x)
{
int temp=ch[x][];
ch[x][]=ch[x][];
ch[x][]=temp;
sign[x]^=;
} inline void pushdown(int x)
{
if( !sign[x] ) return;
if( ch[x][] ) pushr(ch[x][]);
if( ch[x][] ) pushr(ch[x][]);
sign[x]^=;
} inline bool isroot(int x)
{ return (ch[fa[x]][]!=x && ch[fa[x]][]!=x); } inline void rotate(int x)
{
int y=fa[x], z=fa[y];
int k=(ch[y][]==x), w=ch[x][k^];
if( !isroot(y) ) ch[z][ch[z][]==y]=x;
ch[x][k^]=y; ch[y][k]=w;
if( w ) fa[w]=y;
fa[y]=x; fa[x]=z; } inline void splay(int x)
{
top=; q[top]=x;
for(int i=x; !isroot(i); i=fa[i])
q[++top]=fa[i];
while( top ) pushdown(q[top--]);
while( !isroot(x) ) {
int y=fa[x], z=fa[y];
if( !isroot(y) ) {
(ch[z][]==y)^(ch[y][]==x) ?
rotate(x) : rotate(y);
}
rotate(x);
}
} inline void access(int x)
{
for(int y=; x; y=x, x=fa[x])
splay(x), ch[x][]=y;
} inline void makeroot(int x)
{ access(x); splay(x); pushr(x); } inline int findroot(int x)
{
access(x); splay(x);
while( ch[x][] )pushdown(x), x=ch[x][];
splay(x);
return x;
} inline void link(int x,int y)
{ makeroot(x); if( findroot(y)!=x ) fa[x]=y; } inline void cut(int x,int y)
{
makeroot(x);
if( findroot(y)==x && fa[y]==x && !ch[y][] )
fa[y]=ch[x][]=;
}
}T; int main()
{
scanf("%d%d",&n,&m);
char op[]; int x,y;
T.ready();
for(int i=; i<=m; ++i) {
scanf("%s%d%d",op,&x,&y);
if( op[]=='C' ) {
T.link(x,y);
} else if( op[]=='D' ) {
T.cut(x,y);
} else {
if( T.findroot(x)==T.findroot(y) ) printf("Yes\n");
else printf("No\n");
}
}
return ;
}
洛谷P2147 [SDOI2008] 洞穴勘探 [LCT]的更多相关文章
- 洛谷P2147[SDOI2008]洞穴勘测(lct)
题目描述 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假 ...
- 洛谷 P2147 [SDOI2008]洞穴勘测 LCT
Code: #include <cstdio> #include <algorithm> #include <string> #include <cstrin ...
- [洛谷P2147][SDOI2008]洞穴勘测
题目大意:有$n$个洞穴,$m$条指令,指令有三种 $Connect\;u\;v$:在$u,v$之间连一条边 $Destroy\;u\;v$:切断$u,v$之间的边 $Query\;u\;v$:询问$ ...
- 洛谷 P2147 [SDOI2008]洞穴勘测
以下这个做法应该是叫线段树分治... 根据修改操作预处理出每条边存在的时间区间[l,r](以操作序号为时间),然后把所有形式化后的修改挂到线段树节点上. 处理完修改后,dfs一遍线段树,进入某个节点时 ...
- 洛谷 P2147 [SDOI2008]洞穴勘测 (线段树分治)
题目链接 题解 早就想写线段树分治的题了. 对于每条边,它存在于一段时间 我们按时间来搞 我们可把一条边看做一条线段 我们可以模拟线段树操作,不断分治下去 把覆盖\(l-r\)这段时间的线段筛选出来, ...
- 洛谷P2147 [SDOI2008]Cave 洞穴勘测
题目描述 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假 ...
- 【洛谷P2147】洞穴勘测
题目大意:维护 N 个点的无向图,支持动态加边和删边,回答两点的连通性. 题解:线段树分治 + 可撤销并查集 询问可以离线,这是线段树分治的基础. 建立在操作时间轴上的线段树称为线段树分治算法. 本题 ...
- P2147 [SDOI2008]洞穴勘测(LCT)
P2147 [SDOI2008]洞穴勘测 裸的LCT. #include<iostream> #include<cstdio> #include<cstring> ...
- BZOJ 2049 [SDOI2008]洞穴勘测 (LCT)
题目大意:维护一个森林,支持边的断,连,以及查询连通性 LCT裸题 洛谷P2147传送门 1A了,给自己鼓鼓掌 #include <cstdio> #include <algorit ...
随机推荐
- Redis 安装碰到问题
一 make 报错 1. 出现如下错误 : cd src && make all make[1]: Entering directory '/xx/xx/redis-x.x.x/src ...
- HDU 1811 拓扑排序 并查集
有n个成绩,给出m个分数间的相对大小关系,问是否合法,矛盾,不完全,其中即矛盾即不完全输出矛盾的. 相对大小的关系可以看成是一个指向的条件,如此一来很容易想到拓扑模型进行拓扑排序,每次检查当前入度为0 ...
- fastreport中文乱码问题
fastreport的中文乱码问题,确实让人头疼,我使用的是delphi6+fastrepport4.7,在4.7版本中,主要表现在以下几种情况. 预览不乱码,保存乱码. 简体不乱码,繁体乱码. 简体 ...
- Windows下的MySQL删除data文件夹后……
MySQL删除data文件夹后,怎么都无法启动了,出现错误: 150106 9:28:43 [Note] Plugin 'FEDERATED' is disabled. wampmysqld: Tab ...
- DOM使用
DOM树模型 document |-html |-head |-.... |-body |-..... 要解析页面的前提是要拿到一个对象,然后利用树之间前后的关系进行对象的遍历和操作. 在DHTML的 ...
- 【转】CentOS7 yum方式配置LAMP环境
采用Yum方式搭建: Apache+Mysql+PHP环境 原文地址: http://www.cnblogs.com/zutbaz/p/4420791.html 1.安装Apache yum inst ...
- 2017ACM暑期多校联合训练 - Team 2 1003 HDU 6047 Maximum Sequence (线段树)
题目链接 Problem Description Steph is extremely obsessed with "sequence problems" that are usu ...
- Tensorflow常用函数说明(一)
首先最开始应该清楚一个知识,最外面的那个[ [ [ ]]]括号代表第一维,对应维度数字0,第二个对应1,多维时最后一个对应数字-1:因为后面有用到 1 矩阵变换 tf.shape(Tensor) 返回 ...
- 多维数组的字符依次输出,用python实现
#-*- coding=utf-8 -*-listm=["s","l","z","x","l",&q ...
- Android :ExpandableListActivity
http://developer.android.com/reference/android/app/ExpandableListActivity.html# public class Expanda ...