首页 > 代码库 > 脑洞大开加偏执人格——可持久化treap版的Link Cut Tree2

脑洞大开加偏执人格——可持久化treap版的Link Cut Tree2

  试了一下先上再下的Treap方式,很高兴,代码变短了,但是,跑的变慢了!!!其实慢得不多,5%左右。而且这个版本的写法不容易写错。。只要会一般可持久化Treap的人写着都不难。。。就是相对于(压行的)Splay还是长了点。。。

  代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 int father[10010];
  8 struct node
  9 {
 10     int num;
 11     int key;
 12     int left;
 13     int right;
 14     node* ls;
 15     node* rs;
 16     bool turn;
 17     node* f;
 18     node()
 19     {
 20         key=rand();
 21         f=NULL;
 22     }
 23 }no[10010];
 24 
 25 int root;
 26 
 27 void swap(node** a,node** b)
 28 {
 29     node* c=*a;
 30     *a=*b;
 31     *b=c;
 32 }
 33 
 34 void swap(int* a,int *b)
 35 {
 36     int c=*a;
 37     *a=*b;
 38     *b=c;
 39 }
 40 
 41 void pushdown(node* now)
 42 {
 43     if (now->turn)
 44     {
 45         swap(&now->ls,&now->rs);
 46         if (now->ls)
 47         {
 48             now->ls->turn=!now->ls->turn;    
 49             swap(&now->ls->left,&now->ls->right);
 50         }
 51         if (now->rs)
 52         {
 53             now->rs->turn=!now->rs->turn;
 54             swap(&now->rs->left,&now->rs->right);
 55         }
 56     }
 57     now->turn=false;
 58 }
 59 
 60 void update(node* now)
 61 {
 62     now->left=now->right=now->num;
 63     if (now->ls)
 64     {
 65         now->left=now->ls->left;
 66         now->ls->f=now;
 67     }
 68     if (now->rs)
 69     {
 70         now->right=now->rs->right;
 71         now->rs->f=now;
 72     }
 73 }
 74 
 75 node* merge(node* a,node* b)
 76 {
 77     if (!a) {update(b);return b;}
 78     if (!b) {update(a);return a;}
 79     pushdown(a);
 80     pushdown(b);
 81     if (a->key<b->key)
 82     {
 83         a->rs=merge(a->rs,b);
 84         a->rs->f=a;
 85         update(a);
 86         return a;
 87     }
 88     else
 89     {
 90         b->ls=merge(a,b->ls);
 91         b->ls->f=b;
 92         update(b);
 93         return b;
 94     }
 95 }
 96 
 97 struct nodepair 
 98 {
 99     node* l;
100     node* r;
101 
102     nodepair(node* a,node* b)
103     {
104         l=a;
105         r=b;
106     }
107 };
108 
109 bool Ro[30010];
110 int fi=1;
111 
112 int findroot(int num)
113 {
114     node* now=&no[num];
115     while (now->f)
116     {
117         if (now->f->ls==now) Ro[fi++]=true;
118         else
119             Ro[fi++]=false;
120         now=now->f;
121     }
122     return now->num;
123 }
124 
125 nodepair split(node* now,int dep)
126 {
127     if (dep==0)
128     {
129         pushdown(now);
130         nodepair ret(now,now->rs);
131         if (now->rs)
132         {
133             now->rs->f=NULL;
134             now->rs=NULL;
135         }
136         now->f=NULL;
137         update(now);
138         return ret;
139     }
140     if (now->turn) Ro[dep]=!Ro[dep];
141     pushdown(now);
142     if (Ro[dep])
143     {
144         nodepair km=split(now->ls,dep-1);
145         now->ls=km.r;
146         update(now);
147         now->f=NULL;
148         return nodepair(km.l,now);
149     }
150     else
151     {
152         nodepair km=split(now->rs,dep-1);
153         now->rs=km.l;
154         update(now);
155         now->f=NULL;
156         return nodepair(now,km.r);
157     }
158 }
159 
160 nodepair split(int num)
161 {
162     fi=1;
163     int root=findroot(num);
164     return split(&no[root],fi-1);
165 }
166 
167 node* access(int num)
168 {
169     int now=num;
170     node* lasttree=NULL;
171     while (now!=0)
172     {
173         nodepair km=split(now);
174         if (lasttree)
175             father[lasttree->left]=0;
176         lasttree = merge(km.l,lasttree);
177         if (km.r)    
178             father[km.r->left]=now;
179         now=father[lasttree->left];
180     }
181     return lasttree;
182 }
183 
184 bool query(int x,int y)
185 {
186     int k1=access(x)->left;
187     int k2=access(y)->left;
188     return k1==k2;
189 }
190 
191 void changeroot(int n)
192 {
193     node* road=access(n);
194     road->turn=!road->turn;
195     swap(&road->left,&road->right);
196 }
197 
198 void Connect(int x,int y)
199 {
200     changeroot(y);
201     access(x);
202     father[y]=x;
203 }
204 
205 void destroy(int x,int y)
206 {
207     changeroot(x);
208     access(x);
209     father[y]=0;
210 }
211 
212 int main()
213 {
214     int n;
215     cin>>n;
216     for (int i=1;i<=n;++i)
217     {
218         no[i].num=i;
219         father[i]=0;
220     }
221     int q;
222     char cmd[10];
223     scanf("%d",&q);
224     for (int i=1;i<=q;++i)
225     {
226         int j,k;
227         scanf("%s%d%d",cmd,&j,&k);
228         if (cmd[0]==C)
229         {
230             Connect(j,k);
231         }
232         if (cmd[0]==Q)
233         {
234             if (query(j,k))
235                 printf("Yes\n");
236             else
237                 printf("No\n");
238         }
239         if (cmd[0]==D)
240         {
241             destroy(j,k);
242         }
243     }
244     return 0;
245 }
View Code

  我在试试压一下代码吧,总之不想学Splay。。。