_bzoj2049 [Sdoi2008]Cave 洞穴勘测【LCT】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2049

裸的LCT,保存LCT模版。说一下出bug的几个地方叭:

①,rotate时,没有判断y是否为根,这点与普通的Splay有点差别。

②,循环变量是i,而不是x!

#include <cstdio>
#include <algorithm>

const int maxn = 10005;

int n, m, t1, t2;
int ch[maxn][2], fa[maxn], stk[maxn], top;
char opr[10], rev[maxn];

inline bool isroot(int x) {
	return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
}
inline void pushdown(int x) {
	if (rev[x]) {
		rev[x] = 0;
		rev[ch[x][0]] ^= 1;
		rev[ch[x][1]] ^= 1;
		std::swap(ch[x][0], ch[x][1]);
	}
}
inline void rotate(int x) {
	int y = fa[x];
	if (!isroot(y)) {
		if (y == ch[fa[y]][0]) {
			ch[fa[y]][0] = x;
		}
		else {
			ch[fa[y]][1] = x;
		}
	}
	fa[x] = fa[y];
	int dir = x == ch[y][1];
	ch[y][dir] = ch[x][dir ^ 1];
	fa[ch[x][dir ^ 1]] = y;
	ch[x][dir ^ 1] = y;
	fa[y] = x;
}
inline void splay(int x) {
	int p;
	char flag1, flag2;
	top = 0;
	stk[top++] = x;
	for (int i = x; !isroot(i); i = fa[i]) {
		stk[top++] = fa[i];
	}
	for (int i = top - 1; ~i; --i) {
		pushdown(stk[i]);
	}
	while (!isroot(x)) {
		p = fa[x];
		if (isroot(p)) {
			rotate(x);
		}
		else {
			flag1 = p == ch[fa[p]][1];
			flag2 = x == ch[p][1];
			if (flag1 ^ flag2) {
				rotate(x);
			}
			else {
				rotate(p);
			}
			rotate(x);
		}
	}
}
inline void acc(int x) {
	int y = 0;
	while (x) {
		splay(x);
		ch[x][1] = y;
		y = x;
		x = fa[x];
	}
}
inline void make_root(int x) {
	acc(x);
	splay(x);
	rev[x] ^= 1;
}
inline void link(int x, int y) {
	make_root(x);
	fa[x] = y;
}
inline void cutt(int x, int y) {
	make_root(x);
	acc(y);
	splay(y);
	ch[y][0] = fa[x] = 0;
}
inline int fnd_root(int x) {
	acc(x);
	splay(x);
	int i;
	for (i = x; ch[i][0]; i = ch[i][0]);
	return i;
}

int main(void) {
	//freopen("in.txt", "r", stdin);
	scanf("%d%d", &n, &m);
	while (m--) {
		scanf("%s%d%d", opr, &t1, &t2);
		if (opr[0] == ‘Q‘) {
			make_root(t1);
			puts(fnd_root(t2) == t1? "Yes": "No");
		}
		else if (opr[0] == ‘C‘) {
			link(t1, t2);
		}
		else {
			cutt(t1, t2);
		}
	}
	return 0;
}

  

时间: 2024-08-08 13:53:15

_bzoj2049 [Sdoi2008]Cave 洞穴勘测【LCT】的相关文章

BZOJ 2049([Sdoi2008]Cave 洞穴勘测-LCT)[Template:LCT]

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 4809  Solved: 2141 [Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接

[BZOJ2049] [CodeVS1839] [SDOI2008] Cave 洞穴勘测 (LCT)

Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径.洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通

BZOJ 2049 [Sdoi2008]Cave 洞穴勘测 LCT

题意:链接 方法: LCT 解析: 搞了一下午的LCT,这道题就当做第一道模板?题.然后大概写个理解总结什么的. 首先!splay不要写挂!不要写挂! 然后对于这道题.没有什么奇怪的操作. 只有两个操作,将两个节点连起来,将两个节点之间的连边断开. 每一次询问,询问两个节点是否连通. 听起来挺简单的,一下子就想到了并查集有没有! 然而发现并查集并不可以搞. 也许是我太弱,但是我真的不会并查集的分割. 所以还是老老实实来想LCT. LCT 顾名思义,Link Cut 是其比较有代表性的操作? 首先

BZOJ2049: [SDOI2008]Cave 洞穴勘测 LCT

第一道LCT. 动态维护集合就好了. LCT就是一群链通过父亲关系练成一颗不太连续的树,通过儿子关系组成实边,在这里没有查找单点一说,都是直接拎起来,对于一条链他对外界的有用反馈就是他的链父亲以及需求点的真实位置,而每次cut的时候就会把标记下方好,每次spaly都会找到这个点在这条链中的真实位置,因此这个玄妙的东西就形成了. null不是一定要用只是简化了你的讨论. 千万别忘了这里的spaly的特别之处!!!!!!!! #include<cstring> #include<cstdio

bzoj2049: [Sdoi2008]Cave 洞穴勘测 lct裸题

题意:三种操作一种摧毁一条边,一种链接一条边,一种查询两个点是否联通 题解:lct的link和cut即可 /************************************************************** Problem: 2049 User: walfy Language: C++ Result: Accepted Time:1896 ms Memory:1508 kb ************************************************

BZOJ 2049: [Sdoi2008]Cave 洞穴勘测

二次联通门 : BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 其实指针也不是很慢 我的指针代码能吊打70%的数组 及80%的指针.... /* BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 LCT 连边 删边 查询是否在同一树中时, 只需要一直向上跳 看看树根是否相同就好了 */ #include <cstdio> #include <cstdlib> #include <iostream> #define Max 400009 int

【LCT】BZOJ2049 [SDOI2008]Cave 洞穴勘测

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 10059  Solved: 4863[Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起

【bzoj2049】[Sdoi2008]Cave 洞穴勘测 link-cut-tree

2016-05-30  11:04:51 学习了link-cut-tree 二中神犇封禹的讲义感觉讲的超级清晰易懂啊(没有的可以q窝 算是模板吧 #include<bits/stdc++.h> #define N 10005 #define inf 1000000000 #define ll long long using namespace std; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){

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

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 3215  Solved: 1449 [Submit][Status] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞