2049: [Sdoi2008]Cave 洞穴勘测

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 3119  Solved: 1399
[Submit][Status]

Description

辉辉热衷于洞穴勘测。某天,他按照地图来到了一片被标记为JSZX的洞穴群地区。经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴。假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径。洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通道,有时这条通道又会因为某种稀奇古怪的原因被毁。辉辉有一台监测仪器可以实时将通道的每一次改变状况在辉辉手边的终端机上显示:如果监测到洞穴u和洞穴v之间出现了一条通道,终端机上会显示一条指令 Connect u v 如果监测到洞穴u和洞穴v之间的通道被毁,终端机上会显示一条指令 Destroy u v 经过长期的艰苦卓绝的手工推算,辉辉发现一个奇怪的现象:无论通道怎么改变,任意时刻任意两个洞穴之间至多只有一条路径。因而,辉辉坚信这是由于某种本质规律的支配导致的。因而,辉辉更加夜以继日地坚守在终端机之前,试图通过通道的改变情况来研究这条本质规律。然而,终于有一天,辉辉在堆积成山的演算纸中崩溃了……他把终端机往地面一砸(终端机也足够坚固无法破坏),转而求助于你,说道:“你老兄把这程序写写吧”。辉辉希望能随时通过终端机发出指令 Query u v,向监测仪询问此时洞穴u和洞穴v是否连通。现在你要为他编写程序回答每一次询问。已知在第一条指令显示之前,JSZX洞穴群中没有任何通道存在。

Input

第一行为两个正整数n和m,分别表示洞穴的个数和终端机上出现过的指令的个数。以下m行,依次表示终端机上出现的各条指令。每行开头是一个表示指令种类的字符串s("Connect”、”Destroy”或者”Query”,区分大小写),之后有两个整数u和v (1≤u, v≤n且u≠v) 分别表示两个洞穴的编号。

Output

对每个Query指令,输出洞穴u和洞穴v是否互相连通:是输出”Yes”,否则输出”No”。(不含双引号)

Sample Input

样例输入1 cave.in
200 5
Query 123 127
Connect 123 127
Query 123 127
Destroy 127 123
Query 123 127
样例输入2 cave.in

3 5
Connect 1 2
Connect 3 1
Query 2 3
Destroy 1 3
Query 2 3

Sample Output

样例输出1 cave.out
No
Yes
No

样例输出2 cave.out

Yes
No

HINT

数据说明 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操作以免超时

  第一次没有看标程,但是还是面向“数据”编程。这道题易错的部分我已经注释在程序中了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstring>
using namespace std;
#define MAXN 210000
#define MAXT 210000
int n,m;
int ch[MAXT][],pnt[MAXT];
int siz[MAXT];
bool rev[MAXT];
int stack[MAXT],tops=-;
bool is_root(int x)
{
return !pnt[x] || (ch[pnt[x]][]!=x && ch[pnt[x]][]!=x);
}
void update(int now)
{
siz[now]=siz[ch[now][]]+siz[ch[now][]]+;
}
void reverse(int now)
{
if (!now)return ;
swap(ch[now][],ch[now][]);
rev[now]^=;//注意不是给左右儿子打标记
}
void down(int now)
{
if (rev[now])
{
reverse(ch[now][]);
reverse(ch[now][]);
rev[now]=;
}
} void rotate(int now)
{
if (is_root(now))throw "rotate empty node";
int p=pnt[now],anc=pnt[p];
int dir=ch[p][]==now;
if (!is_root(p))
ch[anc][ch[anc][]==p]=now;
pnt[now]=anc;
if (ch[now][dir])
pnt[ch[now][dir]]=p;
ch[p][-dir]=ch[now][dir];
pnt[p]=now;
ch[now][dir]=p;
update(p);
update(now);
}
void splay(int now,int tp=)
{
int x=now;
stack[++tops]=x;//这一句不能漏掉
while(!is_root(x))
{
x=pnt[x];
stack[++tops]=x;
}
while (~tops)down(stack[tops--]);
while (pnt[now]!=tp && !is_root(now))//搞清楚判定条件
{
int p=pnt[now],anc=pnt[p];
if (anc==tp || is_root(p))
{
rotate(now);
}else if ((ch[anc][]==p) == (ch[p][]==now))
rotate(p),rotate(now);
else
rotate(now),rotate(now);
}
}
void access(int now)
{
int son=;
while (now)
{
splay(now);
ch[now][]=son;
update(now);
son=now;
now=pnt[now];
}
}
int get_kth(int now,int rk)
{
if (!now)throw "out of range";
down(now);
if (rk==siz[ch[now][]]+)
return now;
if (rk<siz[ch[now][]]+)
return get_kth(ch[now][],rk);
else
return get_kth(ch[now][],rk-siz[ch[now][]]-);
}
void make_root(int now)
{
access(now);
splay(now);
reverse(now);//旋转整棵树!!(此时ch[now][1]==0)
update(now);
}
int get_root(int now)
{
int res;
while (now)
{
while (!is_root(now))
now=pnt[now];
splay(get_kth(now,));
while (!is_root(now))
now=pnt[now];
res=now;
now=pnt[now];
}
return res;
} int main()
{
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
scanf("%d%d\n",&n,&m);
int i,j,k,x,y,z;
char str[];
for (i=;i<m;i++)
{
scanf("%s %d %d\n",str,&x,&y);
//cout<<str<<" "<<x<<" "<<y<<endl;
if (str[]=='C')//分别旋转为根节点
{
make_root(x);
make_root(y);
pnt[y]=x;
ch[x][]=y;
update(x);
}else if (str[]=='D')//将两点旋转至根节点大小为2的splay中
{
make_root(x);
access(y);
if (ch[y][]==x)splay(x);
else if (ch[x][]==y)splay(y);
if (ch[x][]==y)
{
ch[x][]=pnt[y]=;
update(x);
}else if (ch[y][]==x)
{
ch[y][]=pnt[x]=;
update(y);
}
}else if (str[]=='Q')//将一个点旋转为根,另一点向上走
{
make_root(x);
y=get_root(y);
if (x==y)
{
printf("Yes\n");
}else
{
printf("No\n");
}
}
}
}

bzoj 2049: [Sdoi2008]Cave 洞穴勘测 动态树的更多相关文章

  1. BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 (动态树入门)

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1528  Solved: 644[Submit][ ...

  2. BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 LCT

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...

  3. bzoj 2049: [Sdoi2008]Cave 洞穴勘测 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2049 题面: 2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 1 ...

  4. bzoj 2049 [Sdoi2008]Cave 洞穴勘测(LCT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2049 [题意] 给定森林,可能有连边或断边的操作,回答若干个连通性的询问. [思路] ...

  5. [BZOJ 2049] [Sdoi2008] Cave 洞穴勘测 【LCT】

    题目链接:BZOJ - 2049 题目分析 LCT的基本模型,包括 Link ,Cut 操作和判断两个点是否在同一棵树内. Link(x, y) : Make_Root(x); Splay(x); F ...

  6. 【刷题】BZOJ 2049 [Sdoi2008]Cave 洞穴勘测

    Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...

  7. BZOJ 2049 [Sdoi2008]Cave 洞穴勘测(动态树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2049 [题目大意] 要求支持树的断边和连边,以及连接查询 [题解] LCT练习题 [代 ...

  8. BZOJ 2049: [Sdoi2008]Cave 洞穴勘测——LCT

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2049 省选之前来切一道数据结构模板题. 题意 这是一道模板题. N个点,M次操作,每次加边/ ...

  9. ●BZOJ 2049 [Sdoi2008]Cave洞穴勘测

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2049 题解: LCT入门题 就是判两个点是否在同一颗树里 代码: #include<c ...

随机推荐

  1. Apache Solr配置

    Solr配置 Solr的主要功能是全文检索,该功能分为两个过程:创建索引和对索引进行搜索: 在创建索引之前,需要重点关注两个配置文件:SOLR_HOME/collection1/conf/schema ...

  2. [Redux] Using withRouter() to Inject the Params into Connected Components

    We will learn how to use withRouter() to inject params provided by React Router into connected compo ...

  3. oracle分组查询

    分组函数 在分组函数中,如果有一个查找项分组,其他项必须也分组,比如下面的语句会报错,因为sal分组了,而ename没有分组: 1.显示工资最高的员工: 2.显示所有员工的平均工资: 2.1使用系统函 ...

  4. 基于bootstrap面板的类别多选栏

    1.html部分 <div class="panel panel-default"> <div class="panel-heading"&g ...

  5. 必应代码搜索 Bing Code Search 安装

    微软这几天推出基于bing搜索引擎的  Bing Code Search ,可直接在浏览器上搜索和运行代码.目前中文版必应无法使用本功能,有需要的同学可以转到英文版进行搜索: 英文版必应:  http ...

  6. nginx介绍及安装

    nginx(Engine x)      静态的www软件    特点:        配置简单        高并发,1-2w,基于异步IO模型(epoll,kqueue)        占用资源少 ...

  7. 当append里面的标签显示不出来的时候,用下面的方式做

     $("#result_td").append(tem1+tem3)  $("#result_td").append($(tem1+tem3)) 

  8. PHP 正则通配符

    $a = preg_match('/ph+p/','aaaphpbbbp'); +的前导就是h $a = preg_match('/ph+p/','aaaphhhhhhhhhhpbbbp'); //第 ...

  9. (转)asp.net基础-HttpModule

    HttpModule是向实现类提供模块初始化和处置事件.当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于H ...

  10. [XML] Resource帮助类

    点击下载 Resources.rar /// <summary> /// 类说明:Resources /// 编 码 人:苏飞 /// 联系方式:361983679 /// 更新网站:[u ...