spoj DYNALCA - Dynamic LCA
Posted 哈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spoj DYNALCA - Dynamic LCA相关的知识,希望对你有一定的参考价值。
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 }
以上是关于spoj DYNALCA - Dynamic LCA的主要内容,如果未能解决你的问题,请参考以下文章