[bzoj] 2049: [Sdoi2008]Cave 洞穴勘测 发表于 Apr 6 2015 | 分类于 bzoj | 热烈庆祝我的blog可以显示多行注释了QAQ 题意给定森林,删边添边,查询连通性 分析用一个不常用的GetRoot即可 代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128/****************************************\* Author : ztx* Title : [bzoj] 2049: [Sdoi2008]Cave 洞穴勘测* ALG : LCT复习* CMT :* Time :\****************************************/#include <cstdio>#define Rep(i,l,r) for(i=(l);i<=(r);i++)#define Rev(i,r,l) for(i=(r);i>=(l);i--)typedef long long ll ;inline int GETCHAR() {truestatic const int LEN = 1<<15 ;truestatic char BUF[LEN] , *S = BUF , *T = BUF ;trueif (S == T) {truetrueT = (S=BUF)+fread(BUF , 1 , LEN , stdin) ;truetrueif (S == T) return EOF ;true}truereturn *S ++ ;}int CH , NEG ;template <typename TP>inline void read(TP& ret) { ret = NEG = 0 ; while (CH=GETCHAR() , CH<'!') ; if (CH == '-') NEG = true , CH = GETCHAR() ; while (ret = ret*10+CH-'0' , CH=GETCHAR() , CH>'!') ; if (NEG) ret = -ret ;}template <typename TP>inline void reads(TP& ret) {truewhile (ret=GETCHAR() , ret<'!') ;truewhile (CH=GETCHAR() , CH>'!') ;}#define maxn 10010LLint fa[maxn] = {0} , ch[maxn][2] = {0} ;bool rev[maxn] = {0} ;#define null 0LL#define left(u) ch[u][0]#define right(u) ch[u][1]inline void Exchange(int&a,int&b) {int c=a;a=b;b=c;}inline bool Isrt(int u) { return !fa[u] || (left(fa[u])!=u&&right(fa[u])!=u) ; }inline void Clear(int u) {trueif (!u) return ;trueif (rev[u]) {truetruerev[u] = false ;truetrueExchange(left(u),right(u)) ;truetruerev[left(u)] ^= true ;truetruerev[right(u)] ^= true ;true}}inline void Rot(int x,bool d) {trueint y = fa[x] , z = fa[y] ;trueif (left(z) == y) left(z) = x ;trueelse if (right(z) == y) right(z) = x ;truefa[x] = z , fa[ch[x][d]] = y , ch[y][!d] = ch[x][d] ;truech[x][d] = y , fa[y] = x ;// Maintain(y);}inline void Splay(int x){trueint y , z ;trueClear(x) ;truewhile (!Isrt(x)) {truetruey = fa[x] , z = fa[y] ;truetrueClear(z) , Clear(y) , Clear(x) ;truetrueif (Isrt(y)) Rot(x,ch[y][0]==x) ;truetrueelse if(ch[z][0] == y) {truetruetrueif (ch[y][0] == x) Rot(y,1) ;truetruetrueelse Rot(x,0) ; Rot(x,1) ;truetrue} else {truetruetrueif(ch[y][1] == x) Rot(y,0) ;truetruetrueelse Rot(x,1) ; Rot(x,0) ;truetrue}true}true//Maintain(x) ;}inline void Access(int u) {truefor (int v=null ; u ; right(u)=v,v=u,u=fa[u]) Splay(u) ;}inline void MakeRoot(int u) {trueAccess(u) , Splay(u) , rev[u] ^= true ;}inline void Link(int u , int v) {trueMakeRoot(u) , fa[u] = v ;}inline void Cut(int u , int v) {trueMakeRoot(u) , Access(v) , Splay(v) , fa[u]=left(v)=null ;}inline int GetRoot(int u) {truefor (Access(u),Splay(u) ; Clear(u),left(u) ; u=left(u)) ; return u ;}inline void Query(int u , int v) {trueputs(GetRoot(u)==GetRoot(v) ? "Yes" : "No") ;}int n , m , cmd , u , v ;int main() {// #define READtrue#ifdef READtruetruefreopen(".in" ,"r",stdin ) ;truetruefreopen(".out","w",stdout) ;true#endiftrueread(n) , read(m) ;truewhile (m --> 0) {truetruereads(cmd) , read(u) , read(v) ;truetrueif (cmd == 'C') Link(u,v) ;truetrueif (cmd == 'D') Cut(u,v) ;truetrueif (cmd == 'Q') Query(u,v) ;true}true#ifdef READtruetruefclose(stdin) ; fclose(stdout) ;true#elsetruetruegetchar() ; getchar() ;true#endiftruereturn 0 ;}