zoukankan      html  css  js  c++  java
  • _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;
    }
    

      

  • 相关阅读:
    WPF 使用 Direct2D1 画图 绘制基本图形
    WPF 使用 Direct2D1 画图 绘制基本图形
    dot net core 使用 IPC 进程通信
    dot net core 使用 IPC 进程通信
    win2d 图片水印
    win2d 图片水印
    Java实现 LeetCode 240 搜索二维矩阵 II(二)
    PHP closedir() 函数
    PHP chroot() 函数
    PHP chdir() 函数
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6160371.html
Copyright © 2011-2022 走看看