BZOJ 2049 SDOI2008 洞穴勘测 LCT板子

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2049

 

题意概述:给出N个点,一开始不连通,M次操作,删边加边,保证图是一个森林,询问两点连通性。

N<=10000,M<=200000

 

实际上我就是想来放个LCT板子。。。。。。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #include<set>
 9 #include<map>
10 #include<vector>
11 #include<cctype>
12 using namespace std;
13 
14 int N,M;
15 struct link_cut_tree{
16     static const int maxn=100005;
17     struct node{
18         int ch[2],fa; bool res;
19         node(){ ch[0]=ch[1]=fa=0,res=0; }
20     }nd[maxn];
21     void init(int n) { for(int i=1;i<=n;i++) nd[i].ch[0]=nd[i].ch[1]=nd[i].fa=0,nd[i].res=0; }
22     void link(int x,int d,int y) { nd[x].ch[d]=y,nd[y].fa=x; }
23     bool isrt(int x) { return nd[nd[x].fa].ch[0]!=x&&nd[nd[x].fa].ch[1]!=x; }
24     void pushdown(int x)
25     {
26         if(!nd[x].res) return;
27         int lc=nd[x].ch[0],rc=nd[x].ch[1];
28         if(lc) nd[lc].res^=1,swap(nd[lc].ch[0],nd[lc].ch[1]);
29         if(rc) nd[rc].res^=1,swap(nd[rc].ch[0],nd[rc].ch[1]);
30         nd[x].res=0;
31     }
32     void rot(int x)
33     {
34         int y=nd[x].fa,z=nd[y].fa;
35         pushdown(y);pushdown(x);
36         if(!isrt(y)) link(z,nd[z].ch[1]==y,x); nd[x].fa=z;
37         int d=nd[y].ch[0]==x;
38         link(y,d^1,nd[x].ch[d]);
39         link(x,d,y);
40     }
41     void splay(int x)
42     {
43         pushdown(x);
44         while(!isrt(x)){
45             int y=nd[x].fa,z=nd[y].fa;
46             if(!isrt(y)) rot((nd[y].ch[0]==x)==(nd[z].ch[0]==y)?y:x);
47             rot(x);
48         }
49     }
50     void access(int x)
51     {
52         int y=0;
53         while(x){ splay(x); nd[x].ch[1]=y,y=x,x=nd[x].fa; }
54     }
55     void mroot(int x)
56     {
57         access(x); splay(x);
58         nd[x].res^=1,swap(nd[x].ch[0],nd[x].ch[1]);
59     }
60     void Link(int x,int y) { mroot(x); nd[x].fa=y; }
61     void Cut(int x,int y)
62     {
63         mroot(x); access(y); splay(y);
64         nd[x].fa=nd[y].ch[0]=0;
65     }
66     int find(int x)
67     {
68         access(x); splay(x);
69         while(nd[x].ch[0]){ pushdown(nd[x].ch[0]); x=nd[x].ch[0]; }
70         return x;
71     }
72 }lct;
73 
74 void work()
75 {
76     scanf("%d%d",&N,&M);
77     char op[10]; int x,y;
78     for(int i=1;i<=M;i++){
79         scanf("%s%d%d",op,&x,&y);
80         if(op[0]=='C') lct.Link(x,y);
81         else if(op[0]=='D') lct.Cut(x,y);
82         else if(op[0]=='Q') puts(lct.find(x)==lct.find(y)?"Yes":"No");
83     }
84 }
85 int main()
86 {
87     work();
88     return 0;
89 }

 

posted @ 2018-03-01 15:12  KKKorange  阅读(134)  评论(0编辑  收藏  举报