# [BZOJ 2049] [SDOI2008] Cave 洞穴勘测

## 2049: [SDOI2008]Cave 洞穴勘测

Time Limit: 10 Sec
Memory Limit: 259 MB

200 5
Query 123 127
Connect 123 127
Query 123 127
Destroy 127 123
Query 123 127

3 5
Connect 1 2
Connect 3 1
Query 2 3
Destroy 1 3
Query 2 3

No
Yes
No

Yes
No

## HINT

10%的数据满足n≤1000, m≤20000

20%的数据满足n≤2000, m≤40000

30%的数据满足n≤3000, m≤60000

40%的数据满足n≤4000, m≤80000

50%的数据满足n≤5000, m≤100000

60%的数据满足n≤6000, m≤120000

70%的数据满足n≤7000, m≤140000

80%的数据满足n≤8000, m≤160000

90%的数据满足n≤9000, m≤180000

100%的数据满足n≤10000, m≤200000

## Source

【题解】

 1 #include<bits/stdc++.h>
2 using namespace std;
3 const int MN=10002;
4 struct Node {
5     bool rev;
6     Node *parent, *child[2];
7 }_memory[MN],*EMPTY=_memory;
8 inline void clear(Node* const x) {
9     if (x==EMPTY) return;
10     if (x->rev) {
11         x->child[0]->rev^=1;
12         x->child[1]->rev^=1;
13         swap(x->child[0],x->child[1]);
14         x->rev=false;
15     }
16 }
17 inline void rotate(Node* const x,const int c) {
18     Node* const y=x->parent;
19     y->child[c^1]=x->child[c];
20     if (x->child[c]!=EMPTY) x->child[c]->parent=y;
21     x->parent=y->parent;
22     if (y->parent->child[0]==y) x->parent->child[0]=x;
23     else if (y->parent->child[1]==y) x->parent->child[1]=x;
24     x->child[c]=y;
25     y->parent=x;
26 }
27 inline bool splayy(Node* const x,Node* (&y)) {
28     return (y=x->parent)!=EMPTY && (y->child[0]==x||y->child[1]==x);
29 }
30 inline void splay(Node *const x) {
31     clear(x);
32     for (Node *y,*z;splayy(x,y);)
33         if(splayy(y,z)) {
34             clear(z),clear(y),clear(x);
35             const int c=y==z->child[0];
36             if(x==y->child[c]) rotate(x,c^1),rotate(x,c);
37             else rotate(y,c),rotate(x,c);
38         } else {
39             clear(y);clear(x);
40             rotate(x,x==y->child[0]);
41         }
42 }
43 inline Node* access(Node *u) {
44     Node* v=EMPTY;
45     for(;u!=EMPTY;u=u->parent) {
46         splay(u);
47         u->child[1]=v;
48         v=u;
49     }
50     return v;
51 }
52 inline Node* getroot(Node* x) {
53     for (x=access(x);clear(x),x->child[0]!=EMPTY;x=x->child[0]);
54     return x;
55 }
56 inline void makeroot(Node* const x) {
57     access(x)->rev^=1;
58     splay(x);
59 }
60 void link(Node* const x,Node* const y) {
61     makeroot(x);
62     x->parent=y;
63     access(x);
64 }
65 inline void cut(Node* const x,Node* const y) {
66     makeroot(x);
67     access(y),splay(y);
68     y->child[0]->parent=EMPTY;
69     y->child[0]=EMPTY;
70 }
71 int n,m;
72 int main() {
73     scanf("%d%d",&n,&m);
74     for (int i=0;i<=n;++i) {
75         Node* const node=_memory+i;
76         node->child[0]=node->child[1]=node->parent=EMPTY;
77     }
78     for (int i=0,x,y;i<m;++i) {
79         char buf[10];
80         scanf("\n%s%d%d",buf,&x,&y);
81         Node *ra, *rb;
82         switch(buf[0]) {
83             case 'Q':
84                 ra=getroot(_memory+x),rb=getroot(_memory+y);
85                 printf(ra==rb&&ra!=EMPTY?"Yes\n":"No\n");
86                 break;
87             case 'D': cut(_memory+x,_memory+y); break;
91 }