bzoj 2049 Cave 洞穴勘测(LCT)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
动态树入门题,不需要维护任何信息。
我用的是splay,下标实现的lct。
1 #include <iostream> 2 #include <sstream> 3 #include <ios> 4 #include <iomanip> 5 #include <functional> 6 #include <algorithm> 7 #include <vector> 8 #include <string> 9 #include <list> 10 #include <queue> 11 #include <deque> 12 #include <stack> 13 #include <set> 14 #include <map> 15 #include <cstdio> 16 #include <cstdlib> 17 #include <cmath> 18 #include <cstring> 19 #include <climits> 20 #include <cctype> 21 using namespace std; 22 #define XINF INT_MAX 23 #define INF 0x3FFFFFFF 24 #define MP(X,Y) make_pair(X,Y) 25 #define PB(X) push_back(X) 26 #define REP(X,N) for(int X=0;X<N;X++) 27 #define REP2(X,L,R) for(int X=L;X<=R;X++) 28 #define DEP(X,R,L) for(int X=R;X>=L;X--) 29 #define CLR(A,X) memset(A,X,sizeof(A)) 30 #define IT iterator 31 typedef long long ll; 32 typedef pair<int,int> PII; 33 typedef vector<PII> VII; 34 typedef vector<int> VI; 35 #define MAXN 100010 36 int ch[MAXN][2],key[MAXN],pre[MAXN],size[MAXN],ss[MAXN]; 37 int rev[MAXN]; 38 void push_down(int r){ 39 if(!r)return; 40 if(rev[r]){ 41 rev[ch[r][0]]^=1; 42 rev[ch[r][1]]^=1; 43 swap(ch[r][0],ch[r][1]); 44 rev[r]=0; 45 } 46 } 47 void rotate(int x,int d){ 48 int y=pre[x]; 49 ch[y][!d]=ch[x][d]; 50 if(ch[x][d])pre[ch[x][d]]=y; 51 pre[x]=pre[y]; 52 if(ch[pre[y]][0]==y)ch[pre[x]][0]=x; 53 else if(ch[pre[y]][1]==y)ch[pre[x]][1]=x; 54 pre[y]=x; 55 ch[x][d]=y; 56 } 57 bool check(int x,int y){ 58 return y&&(ch[y][0]==x||ch[y][1]==x); 59 } 60 void splay(int x){ 61 push_down(x); 62 int y,z; 63 while(check(x,y=pre[x])){ 64 if(check(y,z=pre[y])){ 65 push_down(z); 66 push_down(y); 67 push_down(x); 68 int d=(y==ch[z][0]); 69 if(x==ch[y][d]) {rotate(x,!d),rotate(x,d);} 70 else {rotate(y,d),rotate(x,d);} 71 }else{ 72 push_down(y); 73 push_down(x); 74 rotate(x,ch[y][0]==x); 75 break; 76 } 77 } 78 } 79 int access(int u){ 80 int v=0; 81 for(;u;u=pre[u]){ 82 splay(u); 83 ch[u][1]=v; 84 v=u; 85 } 86 //splay(u); 87 return v; 88 } 89 int getroot(int x){ 90 for(x=access(x);push_down(x),ch[x][0];x=ch[x][0]); 91 return x; 92 } 93 void makeroot(int x){ 94 rev[access(x)]^=1; 95 splay(x); 96 } 97 void link(int x,int y){ 98 makeroot(x); 99 pre[x]=y; 100 access(x); 101 } 102 void cut(int x,int y){ 103 makeroot(x); 104 access(y); 105 splay(y); 106 pre[ch[y][0]]=0; 107 ch[y][0]=0; 108 } 109 void init(int n){ 110 for(int i=0;i<=n;i++) 111 ch[i][0]=ch[i][1]=pre[i]=0; 112 } 113 void query(int x,int y){ 114 int ra=getroot(x); 115 int rb=getroot(y); 116 if(ra==rb&&ra)printf("Yes\n"); 117 else printf("No\n"); 118 } 119 120 int main() 121 { 122 ios::sync_with_stdio(false); 123 int n,m; 124 while(scanf("%d%d",&n,&m)!=EOF){ 125 init(n); 126 int x,y; 127 char a[110]; 128 for(int i=0;i<m;i++){ 129 scanf("%s%d%d",a,&x,&y); 130 if(a[0]=='C')link(x,y); 131 else if(a[0]=='D')cut(x,y); 132 else query(x,y); 133 } 134 } 135 return 0; 136 }