http://www.spoj.com/problems/DYNALCA/
此题link、cut要求不能换根,当然也保证link时其中一个点必定已经是根。
方法:
void link(Node *x,Node *y)
{
access(x);splay(x);
x->fa=y;
}
void cut(Node *x)
{
access(x);splay(x);
x->ch[0]->fa=NULL;x->ch[0]=NULL;
}
曾经的错误思路:
void cut(Node *x)
{
access(x->fa);x->fa=NULL;
}
因为此时x->fa不一定是splay维护的序列上x的前一个元素(只是splay上x的父亲罢了,在实际序列中它们的关系可以任意)
求lca?x,y的lca就是先access(x)后,在access(y)的过程中,“最后一次虚边变成实边的位置”。实际也就是access(y)的过程中最后一次的lst
1 #include<cstdio>
2 #include<algorithm>
3 using namespace std;
4 namespace LCT
5 {
6 struct Node
7 {
8 Node *ch[2],*fa;
9 bool rev;
10 int num;
11 void upd() {}
12 void pd()
13 {
14 if(rev)
15 {
16 swap(ch[0],ch[1]);
17 if(ch[0]) ch[0]->rev^=1;
18 if(ch[1]) ch[1]->rev^=1;
19 rev=0;
20 }
21 }
22 }nodes[100100];
23 int mem;
24 Node *getnode()
25 {
26 return nodes+(mem++);
27 }
28 bool isroot(Node *x)
29 {
30 return (!x->fa)||((x->fa->ch[0]!=x)&&(x->fa->ch[1]!=x));
31 }
32 bool gson(Node *o) {return o==o->fa->ch[1];}
33 void rotate(Node *o,bool d)
34 {
35 Node *k=o->ch[!d];if(!isroot(o)) o->fa->ch[gson(o)]=k;
36 o->ch[!d]=k->ch[d];k->ch[d]=o;
37 o->upd();k->upd();
38 k->fa=o->fa;o->fa=k;if(o->ch[!d]) o->ch[!d]->fa=o;
39 }
40 Node *st[300100];int top;
41 void solvetag(Node *o)
42 {
43 while(!isroot(o)) st[++top]=o,o=o->fa;
44 st[++top]=o;
45 while(top) st[top--]->pd();
46 }
47 void splay(Node *o)
48 {
49 solvetag(o);
50 Node *fa,*fafa;bool d1,d2;
51 while(!isroot(o))
52 {
53 fa=o->fa;d1=(o==fa->ch[0]);
54 if(isroot(fa)) rotate(fa,d1);
55 else
56 {
57 fafa=o->fa->fa;d2=(fa==fafa->ch[0]);
58 if(d1==d2) rotate(fafa,d1),rotate(fa,d1);
59 else rotate(fa,d1),rotate(fafa,d2);
60 }
61 }
62 }
63 void access(Node *o)
64 {
65 for(Node *lst=NULL;o;lst=o,o=o->fa)
66 {
67 splay(o);
68 o->ch[1]=lst;o->upd();
69 }
70 }
71 Node *gtop(Node *o)
72 {
73 access(o);splay(o);
74 for(;o->ch[0];o=o->ch[0],o->pd());
75 splay(o);return o;
76 }
77 void mtop(Node *o) {access(o);splay(o);o->rev^=1;}
78 void link(Node *x,Node *y)
79 {
80 access(x);splay(x);
81 x->fa=y;
82 }
83 //void splay(Node *o,Node *rt)
84 //{
85 // if(isroot(rt)) splay(o);
86 // bool d=gson(rt);Node *t=rt->fa;
87 // t->ch[d]=NULL;rt->fa=NULL;
88 // splay(o);
89 // t->ch[d]=o;o->fa=t;
90 //}
91 void cut(Node *x)
92 {
93 access(x);splay(x);
94 x->ch[0]->fa=NULL;x->ch[0]=NULL;
95 }
96 Node *lca(Node *x,Node *y)
97 {
98 access(x);Node *lst=NULL;
99 for(;y;lst=y,y=y->fa)
100 {
101 splay(y);
102 y->ch[1]=lst;y->upd();
103 }
104 return lst;
105 }
106 }
107 LCT::Node *nd[300100];
108 int n,q;char tmp[20];
109 int main()
110 {
111 int i,x,y;
112 scanf("%d%d",&n,&q);
113 for(i=1;i<=n;i++)
114 {
115 nd[i]=LCT::getnode();
116 nd[i]->num=i;
117 }
118 while(q--)
119 {
120 scanf("%s",tmp);
121 switch(tmp[1])
122 {
123 case 'i':
124 scanf("%d%d",&x,&y);
125 LCT::link(nd[x],nd[y]);
126 break;
127 case 'u':
128 scanf("%d",&x);
129 LCT::cut(nd[x]);
130 break;
131 case 'c':
132 scanf("%d%d",&x,&y);
133 printf("%d\n",LCT::lca(nd[x],nd[y])->num);
134 break;
135 }
136 }
137 return 0;
138 }