脑洞大开加偏执人格——可持久化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 }

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

脑洞大开加偏执人格——可持久化treap版的Link Cut Tree2,布布扣,bubuko.com

时间: 2024-10-23 10:31:57

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

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

一直没有点动态树这个科技树,因为听说只能用Splay,用Treap的话多一个log.有一天脑洞大开,想到也许Treap也能从底向上Split.仔细思考了一下,发现翻转标记不好写,再仔细思考了一下,发现还是可以写的,只需要实时交换答案二元组里的两棵树,最后在吧提出来的访问节点放回去就行了.本着只学一种平衡树的想法,脑洞大开加偏执人格的开始写可持久化Treap版的Link Cut Tree... 写了才发现,常数硕大啊!!!代码超长啊!!!因为merge是从上到下,split从下到上,pushdow

UVALive 6145 Version Controlled IDE(可持久化treap、rope)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4156 题目拷贝难度大我就不复制了. 题目大意:维护一个字符串,要求支持插入.删除操作,还有输出第 i 次操作后的某个子串.强制在线. 思路1:使用可持久化treap可破,详细可见CLJ的<可持久化数据结构的研究>. 思路2:rope大法好,详见:http

好久不见的博客咯!——没有可持久化的可持久化treap

每每想要去了解可持久化treap这个好写好调的东东,然后就发现网上只有一个人的--SymenYang的!在此我必须得把他批判一番--写方法不贴代码是什么心态!而且写出来的是有问题的呀!害人不浅! 好吧说正经事,这个版本的treap名叫可持久化treap却没有可持久化,而是借鉴了可持久化treap中的一些写法.貌似可持久化之后反而难写难调...在这个版本的treap中加入了堆权值来维护树的形状,然后由三种操作--合并(merge),按size拆分(split_size),按值拆分(split_kt

BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap

3595: [Scoi2014]方伯伯的OjTime Limit: 6 Sec  Memory Limit: 256 MBSubmit: 102  Solved: 54[Submit][Status] Description 方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题. Oj上注册了n个用户,编号为1-",一开始他们按照编号排名.方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和编号: 1.操作格式为1 x y,意味着将编号为z的用户编号改为V,而排名不变,执行完该操作后需要

HDOJ 题目3966 Aragorn&#39;s Story(Link Cut Tree成段加减点权,查询点权)

Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5505    Accepted Submission(s): 1441 Problem Description Our protagonist is the handsome human prince Aragorn comes from The Lor

可持久化Treap(fhq Treap,非旋转式Treap)学习(未完待续)

简介: Treap,一种表现优异的BST 优势: 其较于AVL.红黑树实现简单,浅显易懂 较于Splay常数小,通常用于树套BST表现远远优于Splay 或许有人想说SBT,SBT我没有实现过,据说比较快 但是SBT.Splay以及旋转版Treap等BST都不可以比较方便地实现‘可持久化操作 Treap=Tree+Heap Treap是一颗同时拥有二叉搜索树和堆性质的一颗二叉树 Treap有两个关键字,在这里定义为: 1.key,满足二叉搜索树性质,即中序遍历按照key值有序 2.fix,满足堆

Android数据加载及Json解析——框架版

方法调用 new ApiUser(this).initData(new ApiRequest() { @Override public void onResult(BeanRequest bean) { //如果接口调用不成功,给予提示 if (!bean.isSuccess()) { UtilToast.show(Activitymain.this, bean.getErrInfo(), UtilToast.STYLE_ERROR); } //Json数据解析:BeanInitData 数据实

spring编程式刷新/重新加载applicationcontext/dispatchservlet(正确版)

有些时候,尤其是在开发应用框架的时候,由于某些原因无法或者很难重启tomcat或者reload应用,但是配置又需要动态生效,这个时候通常希望通过reload spring applicationcontext的方式来重新加载配置,比如数据源的动态配置. 1.在web.xml配置监听器ContextLoaderListener <listener>   <listener-class>org.springframework.web.context.ContextLoaderListe

Android数据加载及Json解析——原始版

1.创建要下载数据的实体类 class MyData { String imagepath; String title; String desc; public MyData(String imagepath, String title, String desc) { super(); this.imagepath = imagepath; this.title = title; this.desc = desc; } } 2.AsyncTask数据加载及Json解析类 class FileAs