zoukankan      html  css  js  c++  java
  • BZOJ 2049: [Sdoi2008]Cave 洞穴勘测——LCT

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

    省选之前来切一道数据结构模板题。

    题意

    这是一道模板题

    N个点,M次操作,每次加边/删边/询问两个点是否连通,保证每次操作之后仍然是一棵树。

    N<=1e4,M<=2e5。

    做法

    裸的LCT。

    需要支持查找一个点所在树的根,只要不断向上查找father就行了。

    (fread就是快啊。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=20005, MAXB=2e7;
    char BUF[MAXB], *cp=BUF;
    void rd(int &x){
    	x=0;
    	while(*cp<'0'||'9'<*cp) cp++;
    	while('0'<=*cp&&*cp<='9') x=x*10+*cp-'0', cp++;
    }
    char rdc(){
    	while(*cp<'A'||'Z'<*cp) cp++;
    	return *cp;
    }
    
    int N, M, top;
    
    struct Node{
    	Node *ch[2], *fa;
    	int re;
    }nd[MAXN], *rt, *st[MAXN];
    
    inline int isrt(Node *x){return !(x->fa->ch[0]==x||x->fa->ch[1]==x);}
    
    void rot(Node *x){
    	Node *y=x->fa, *z=y->fa;
    	int l=y->ch[1]==x, r=!l;
    	if(!isrt(y)) z->ch[z->ch[1]==y]=x;
    	x->ch[r]->fa=y; y->fa=x; x->fa=z;
    	y->ch[l]=x->ch[r]; x->ch[r]=y;
    }
    
    void down(Node *x){
    	if(x->re){
    		x->ch[0]->re^=1; x->ch[1]->re^=1;
    		swap(x->ch[0], x->ch[1]); x->re=0;
    	}
    }
    
    void splay(Node *x){
    	st[top++]=x;
    	for(Node *i=x; !isrt(i); i=i->fa) st[top++]=i->fa;
    	for(;top;--top) down(st[top-1]);
    	while(!isrt(x)){
    		Node *y=x->fa, *z=y->fa;
    		if(!isrt(y)) rot((z->ch[1]==y)^(y->ch[1]==x)?x:y);
    		rot(x);
    	}
    }
    
    inline void access(Node *x){
    	for(Node *i=nd; x!=nd; i=x,x=x->fa)
    		splay(x), x->ch[1]=i;
    }
    
    inline void mkrt(Node *x){access(x),splay(x),x->re^=1;}
    
    inline Node *getrt(Node *x){while(x->fa!=nd)x=x->fa; return x;}
    
    inline void lin(Node *x, Node *y){mkrt(x); x->fa=y;}
    
    inline void cut(Node *x, Node *y){
    	mkrt(x); access(y); splay(y);
    	y->ch[0]=x->fa=nd;
    }
    
    int main(){
    	fread(BUF, 1, MAXB, stdin);
    	rd(N),rd(M);
    	for(int i=0; i<=N; ++i) nd[i].ch[0]=nd[i].ch[1]=nd[i].fa=nd;
    	for(int i=0,u,v; i<M; ++i){
    		char ch=rdc(); rd(u), rd(v);
    		if(ch=='Q') puts(getrt(nd+u)==getrt(nd+v)?"Yes":"No");
    		else if(ch=='C') lin(nd+u,nd+v);
    		else cut(nd+u,nd+v);
    	}
    	return 0;
    }
    
  • 相关阅读:
    数据预处理
    机器学习--有监督学习和无监督学习
    weka简介
    第10章 接口、继承与多态----类的继承3
    html5 canvas实现梦幻的3D刺猬球
    html5 canvas实现图片玻璃碎片特效
    css3实现的鼠标经过按钮特效
    CSS3 Transitions属性打造动画的下载按钮特效
    纯css3实现的幽灵按钮导航
    几行css3代码实现超炫加载动画
  • 原文地址:https://www.cnblogs.com/will7101/p/6675237.html
Copyright © 2011-2022 走看看