[BZOJ 2049] [Sdoi2008] Cave 洞穴勘测 【LCT】
题目链接:BZOJ - 2049
题目分析
LCT的基本模型,包括 Link ,Cut 操作和判断两个点是否在同一棵树内。
Link(x, y) : Make_Root(x); Splay(x); Father[x] = y;
Cut(x, y) : Make_Root(x); Access(y); 断掉 y 和 Son[y][0]; 注意修改 Son[y][0] 的 isRoot 和 Father
判断 x, y 是否在同一棵数内,我们就看两个点所在树的根是否相同,使用 Find_Root();
Find_Root(x) : Access(x); Splay(x); while (Son[x][0] != 0) x = Son[x][0]; 然后 x 就是树根了。
代码
- #include <iostream>
- #include <cstdlib>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- using namespace std;
- inline void Read(int &Num)
- {
- char c = getchar();
- bool Neg = false;
- while (c < '0' || c > '9')
- {
- if (c == '-') Neg = true;
- c = getchar();
- }
- Num = c - '0'; c = getchar();
- while (c >= '0' && c <= '9')
- {
- Num = Num * 10 + c - '0';
- c = getchar();
- }
- if (Neg) Num = -Num;
- }
- const int MaxN = 10000 + 5;
- int n, m;
- int Father[MaxN], Son[MaxN][2];
- bool isRoot[MaxN], Rev[MaxN];
- inline void Reverse(int x)
- {
- Rev[x] = !Rev[x];
- swap(Son[x][0], Son[x][1]);
- }
- inline void PushDown(int x)
- {
- if (!Rev[x]) return;
- Rev[x] = false;
- if (Son[x][0]) Reverse(Son[x][0]);
- if (Son[x][1]) Reverse(Son[x][1]);
- }
- void Rotate(int x)
- {
- int y = Father[x], f;
- PushDown(y); PushDown(x);
- if (x == Son[y][0]) f = 1;
- else f = 0;
- if (isRoot[y])
- {
- isRoot[y] = false;
- isRoot[x] = true;
- }
- else
- {
- if (y == Son[Father[y]][0]) Son[Father[y]][0] = x;
- else Son[Father[y]][1] = x;
- }
- Father[x] = Father[y];
- Son[y][f ^ 1] = Son[x][f];
- if (Son[x][f]) Father[Son[x][f]] = y;
- Son[x][f] = y;
- Father[y] = x;
- }
- void Splay(int x)
- {
- int y;
- while (!isRoot[x])
- {
- y = Father[x];
- if (isRoot[y])
- {
- Rotate(x);
- break;
- }
- if (y == Son[Father[y]][0])
- {
- if (x == Son[y][0])
- {
- Rotate(y);
- Rotate(x);
- }
- else
- {
- Rotate(x);
- Rotate(x);
- }
- }
- else
- {
- if (x == Son[y][1])
- {
- Rotate(y);
- Rotate(x);
- }
- else
- {
- Rotate(x);
- Rotate(x);
- }
- }
- }
- }
- int Access(int x)
- {
- int y = 0;
- while (x != 0)
- {
- Splay(x);
- PushDown(x);
- isRoot[Son[x][1]] = true;
- Son[x][1] = y;
- if (y) isRoot[y] = false;
- y = x;
- x = Father[x];
- }
- return y;
- }
- void Make_Root(int x)
- {
- int t = Access(x);
- Reverse(t);
- }
- int Find_Root(int x)
- {
- int t = Access(x);
- while (Son[t][0] != 0) t = Son[t][0];
- return t;
- }
- int main()
- {
- scanf("%d%d", &n, &m);
- for (int i = 1; i <= n; ++i)
- {
- isRoot[i] = true;
- Father[i] = 0;
- }
- char Str[10];
- int a, b, x, y;
- for (int i = 1; i <= m; ++i)
- {
- scanf("%s", Str);
- Read(a); Read(b);
- if (strcmp(Str, "Connect") == 0)
- {
- Make_Root(a);
- Splay(a);
- Father[a] = b;
- }
- else if (strcmp(Str, "Destroy") == 0)
- {
- Make_Root(a);
- Access(b);
- Splay(b);
- PushDown(b);
- isRoot[Son[b][0]] = true;
- Father[Son[b][0]] = 0;
- Son[b][0] = 0;
- }
- else
- {
- x = Find_Root(a);
- y = Find_Root(b);
- if (x == y) printf("Yes\n");
- else printf("No\n");
- }
- }
- return 0;
- }
[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 洞穴勘测
Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...
- bzoj 2049 [Sdoi2008]Cave 洞穴勘测(LCT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2049 [题意] 给定森林,可能有连边或断边的操作,回答若干个连通性的询问. [思路] ...
- 【BZOJ】2049: [Sdoi2008]Cave 洞穴勘测 LCT
[题意]给定n个点和m个操作,每次操作:1.连接2个点.2.断开2个点.3.查询2个点是否连通.m<=2*10^5. [算法]Link-Cut Tree [题解]LCT模板题,Link,Cut, ...
随机推荐
- [互联网面试笔试汇总C/C++-7] 寻找两个链表的第一个交点-微策略
题目:有两个链表,找出他们的第一个交点,要求每个链表只能遍历一次,可以对链表进行任何操作,空间O(1). 思路: 这个题目刚开始看觉得要遍历一次有点困难,但是仔细一想,人家告诉说可以对链表进行任何操作 ...
- 5 Ways to Use Log Data to Analyze System Performance--reference
Recently we looked across some of the most common behaviors that our community of 25,000 users looke ...
- adb取出安装在手机中的apk
Android实战技巧之十八:adb取出安装在手机中的apk 场景: 朋友看见你Android手机中的游戏或应用很好玩,也想装一个此程序,但限于网络条件不能从网上下载.那么最简单的办法就是直接从你手机 ...
- CXF整合Spring开发WebService
刚开始学webservice时就听说了cxf,一直没有尝试过,这两天试了一下,还不错,总结如下: 要使用cxf当然是要先去apache下载cxf,下载完成之后,先要配置环境变量,有以下三步: 1.打开 ...
- Linux下搭建Oracle11g RAC(6)----安装Grid Infrastructure
从此步骤开始,我们正式安装Grid软件: ① 以grid用户登录图形界面,执行/home/grid/grid/runInstaller,进入OUI的图形安装界面: ② 进入OUI安装界面后,选择第3项 ...
- 【原】个人对win7开机黑屏只有鼠标排障总结
个人对win7开机黑屏只有鼠标排障总结 文:铁乐猫 第一种情况是explorer.exe进程丢失或损坏有关: 判断方法是按Ctrl+Alt+Del键能呼出任务管理器,结束explorer.exe进程, ...
- C#/.net七牛云存储上传图片(文件)操作
七牛云存储官方: C#SDK(http://developer.qiniu.com/docs/v6/sdk/csharp-sdk.html) 注册成为标准用户就可获得:10GB永久免费存储空间/ 每月 ...
- 【锋利的jQuery】学习笔记01
第一章 认识jQuery 一.常见的JS库 Prototype 最早的js库之一.把好用JS方法组合,缺点结构松散. Dojo 离线存储API.生成图标组件.矢量图形库.Comet支持.企业级JS库, ...
- c语言学习之基础知识点介绍(一):输出语句和变量简单介绍
本系列是为了学习ios做准备的,也能作为c语言入门的教程看看. c语言的程序结构: 1.顺序结构:自上而下依次执行. 2.分支结构:程序有选择的执行某段代码或者不执行某段代码. 3.循环结构:程序循环 ...
- 这次是C#中的接口
接口的出现,是为了解决C#中不允许多重继承的问题. 1.什么是接口? 我觉得可以把接口理解为对一组方法声明进行的统一命名,但这些方法没有提供任何实现. 通过接口,就可以对方法进行统一管理,避免了在每种 ...