BZOJ2049: [Sdoi2008]Cave 洞穴勘测

n<=10000个点,m<=200000个操作,连接,断边,问两个点是否连通,保证连接过程中每个联通块都是树。

LCT。。

  1 #include<string.h>
  2 #include<stdlib.h>
  3 #include<stdio.h>
  4 #include<math.h>
  5 //#include<assert.h>
  6 #include<algorithm> 
  7 //#include<iostream>
  8 //#include<bitset>
  9 using namespace std;
 10 
 11 int n,m;
 12 #define maxn 10011
 13 struct LCT
 14 {
 15     struct Node
 16     {
 17         int fa,son[2];
 18         bool rev;
 19         int size;
 20     }a[maxn];
 21     void makeatree(int id)
 22     {
 23         a[id].fa=a[id].son[0]=a[id].son[1]=a[id].rev=0;
 24         a[id].size=1;
 25     }
 26     void up(int x)
 27     {
 28         if (!x) return;
 29         int &p=a[x].son[0],&q=a[x].son[1];
 30         a[x].size=a[p].size+a[q].size+1;
 31     }
 32     void revsingle(int x)
 33     {
 34         if (!x) return;
 35         a[x].rev^=1;
 36         int &p=a[x].son[0],&q=a[x].son[1];
 37         p^=q; q^=p; p^=q;
 38     }
 39     void down(int x)
 40     {
 41         int &p=a[x].son[0],&q=a[x].son[1];
 42         if (a[x].rev) {revsingle(p); revsingle(q); a[x].rev=0;}
 43     }
 44     int sta[maxn];
 45     void download(int x)
 46     {
 47         int top=0; for (;!isroot(x);x=a[x].fa) sta[++top]=x; sta[++top]=x;
 48         for (;top;top--) down(sta[top]);
 49     }
 50     bool isroot(int x)
 51     {
 52         if (!a[x].fa) return 1;
 53         return (a[a[x].fa].son[0]!=x && a[a[x].fa].son[1]!=x);
 54     }
 55     void rotate(int x)
 56     {
 57         const int y=a[x].fa,z=a[y].fa;
 58         bool w=(x==a[y].son[0]);
 59         a[x].fa=z;
 60         if (!isroot(y)) a[z].son[y==a[z].son[1]]=x;
 61         a[y].son[w^1]=a[x].son[w];
 62         if (a[x].son[w]) a[a[x].son[w]].fa=y;
 63         a[x].son[w]=y;
 64         a[y].fa=x;
 65         up(y); up(z);
 66     }
 67     void splay(int x)
 68     {
 69         if (!x) return;
 70         download(x);
 71         while (!isroot(x))
 72         {
 73             const int y=a[x].fa,z=a[y].fa;
 74             if (!isroot(y))
 75             {
 76                 if ((x==a[y].son[0])^(y==a[z].son[0])) rotate(x);
 77                 else rotate(y);
 78             }
 79             rotate(x);
 80         }
 81         up(x);
 82     }
 83     void access(int x)
 84     {
 85         int y=0,tmp=x;
 86         while (x) {splay(x); a[x].son[1]=y; up(x); y=x; x=a[x].fa;}
 87         splay(tmp);
 88     }
 89     void resetroot(int x)
 90     {
 91         access(x);
 92         revsingle(x);
 93     }
 94     void link(int x,int y)
 95     {
 96         resetroot(x);
 97         a[x].fa=y;
 98     }
 99     void cut(int x,int y)
100     {
101         resetroot(x);
102         access(y);
103         a[y].son[0]=a[x].fa=0;
104         up(y);
105     }
106     int findroot(int x)
107     {
108         while (a[x].fa) x=a[x].fa;
109         return x;
110     }
111 }t;
112 
113 int main()
114 {
115     scanf("%d%d",&n,&m);
116     for (int i=1;i<=n;i++) t.makeatree(i);
117     char c;int x,y;
118     while (m--)
119     {
120         while ((c=getchar())!='C' && c!='D' && c!='Q');
121         if (c=='C')
122         {
123             while ((c=getchar())>='a' && c<='z');
124             scanf("%d%d",&x,&y);
125             t.link(x,y);
126         }
127         else if (c=='D')
128         {
129             while ((c=getchar())>='a' && c<='z');
130             scanf("%d%d",&x,&y);
131             t.cut(x,y);
132         }
133         else if (c=='Q')
134         {
135             while ((c=getchar())>='a' && c<='z');
136             scanf("%d%d",&x,&y);
137             puts(t.findroot(x)==t.findroot(y)?"Yes":"No");
138         }
139     }
140     return 0;
141 }
View Code

 

posted @ 2018-01-15 20:58  Blue233333  阅读(144)  评论(0编辑  收藏  举报