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

  代码:

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm> using namespace std;
int father[];
struct node
{
int num;
int key;
int left;
int right;
node* ls;
node* rs;
bool turn;
node* f;
node()
{
key=rand();
f=NULL;
}
}no[]; int root; void swap(node** a,node** b)
{
node* c=*a;
*a=*b;
*b=c;
} void swap(int* a,int *b)
{
int c=*a;
*a=*b;
*b=c;
} void pushdown(node* now)
{
if (now->turn)
{
swap(&now->ls,&now->rs);
if (now->ls)
{
now->ls->turn=!now->ls->turn;
swap(&now->ls->left,&now->ls->right);
}
if (now->rs)
{
now->rs->turn=!now->rs->turn;
swap(&now->rs->left,&now->rs->right);
}
}
now->turn=false;
} void update(node* now)
{
now->left=now->right=now->num;
if (now->ls)
{
now->left=now->ls->left;
now->ls->f=now;
}
if (now->rs)
{
now->right=now->rs->right;
now->rs->f=now;
}
} node* merge(node* a,node* b)
{
if (!a) {update(b);return b;}
if (!b) {update(a);return a;}
pushdown(a);
pushdown(b);
if (a->key<b->key)
{
a->rs=merge(a->rs,b);
a->rs->f=a;
update(a);
return a;
}
else
{
b->ls=merge(a,b->ls);
b->ls->f=b;
update(b);
return b;
}
} struct nodepair
{
node* l;
node* r; nodepair(node* a,node* b)
{
l=a;
r=b;
}
}; bool Ro[];
int fi=; int findroot(int num)
{
node* now=&no[num];
while (now->f)
{
if (now->f->ls==now) Ro[fi++]=true;
else
Ro[fi++]=false;
now=now->f;
}
return now->num;
} nodepair split(node* now,int dep)
{
if (dep==)
{
pushdown(now);
nodepair ret(now,now->rs);
if (now->rs)
{
now->rs->f=NULL;
now->rs=NULL;
}
now->f=NULL;
update(now);
return ret;
}
if (now->turn) Ro[dep]=!Ro[dep];
pushdown(now);
if (Ro[dep])
{
nodepair km=split(now->ls,dep-);
now->ls=km.r;
update(now);
now->f=NULL;
return nodepair(km.l,now);
}
else
{
nodepair km=split(now->rs,dep-);
now->rs=km.l;
update(now);
now->f=NULL;
return nodepair(now,km.r);
}
} nodepair split(int num)
{
fi=;
int root=findroot(num);
return split(&no[root],fi-);
} node* access(int num)
{
int now=num;
node* lasttree=NULL;
while (now!=)
{
nodepair km=split(now);
if (lasttree)
father[lasttree->left]=;
lasttree = merge(km.l,lasttree);
if (km.r)
father[km.r->left]=now;
now=father[lasttree->left];
}
return lasttree;
} bool query(int x,int y)
{
int k1=access(x)->left;
int k2=access(y)->left;
return k1==k2;
} void changeroot(int n)
{
node* road=access(n);
road->turn=!road->turn;
swap(&road->left,&road->right);
} void Connect(int x,int y)
{
changeroot(y);
access(x);
father[y]=x;
} void destroy(int x,int y)
{
changeroot(x);
access(x);
father[y]=;
} int main()
{
int n;
cin>>n;
for (int i=;i<=n;++i)
{
no[i].num=i;
father[i]=;
}
int q;
char cmd[];
scanf("%d",&q);
for (int i=;i<=q;++i)
{
int j,k;
scanf("%s%d%d",cmd,&j,&k);
if (cmd[]=='C')
{
Connect(j,k);
}
if (cmd[]=='Q')
{
if (query(j,k))
printf("Yes\n");
else
printf("No\n");
}
if (cmd[]=='D')
{
destroy(j,k);
}
}
return ;
}

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

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

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

    一直没有点动态树这个科技树,因为听说只能用Splay,用Treap的话多一个log.有一天脑洞大开,想到也许Treap也能从底向上Split.仔细思考了一下,发现翻转标记不好写,再仔细思考了一下,发现 ...

  2. 平衡树与可持久化treap

    平衡树(二叉树) 线段树不支持插入or删除一个数于是平衡树产生了 常见平衡树:treap(比sbt慢,好写吧),SBT(快,比较好写,有些功能不支持),splay(特别慢,复杂度当做根号n来用,功能强 ...

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

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

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

    3595: [Scoi2014]方伯伯的Oj Time Limit: 6 Sec  Memory Limit: 256 MBSubmit: 102  Solved: 54[Submit][Status ...

  5. 【模板】可持久化文艺平衡树-可持久化treap

    题目链接 题意 对于各个以往的历史版本实现以下操作: 在第 p 个数后插入数 x . 删除第 p 个数. 翻转区间 [l,r],例如原序列是 \(\{5,4,3,2,1\}\),翻转区间 [2,4] ...

  6. 高rong效chang的可持久化treap

    很多人觉得可持久化treap很慢,但是事实上只是他们可持久化treap的写法不对.他们一般是用split和merge实现所有功能,但是这样会有许多不必要的分裂.其实我们可以用一种特殊的方式来实现插入和 ...

  7. 可持久化Treap

    终于写了一次可持久化Treap,做的是可持久化序列的模板题. Treap Treap=Tree+Heap,是一个随机化的数据结构.它的每个节点至少有两个关键字,一个是我们要存储的\(val\),一个是 ...

  8. Codeforces - 38G 可持久化Treap 区间操作

    题意:\(n\)个人排队,每个人有重要度\(p\)和不要脸度\(c\),如果第\(i\)个人的重要度大于第\(i-1\)个人的重要度,那么他们之间可以交换,不要脸度-1,交换后先前的第\(i\)个人也 ...

  9. Codeforces - 675D 可持久化Treap 树形操作

    题意:模拟二叉树的构造过程,给出\(n\)个节点,每次从根插入,小于当前节点转到左儿子,否则右儿子,输出第\([2,n]\)个节点的父亲的权值 直接手动模拟会被链式结构T掉 网上找了下发现二叉树的性质 ...

随机推荐

  1. common_functions.h:64:24: error: token ""__CUDACC_VER__ is no longer supported.

    问题在复现工程https://github.com/google/hdrnet时出现. 现象: 解决: TensorFlow版本问题,升级到版本1.10.0之后,问题解决.

  2. git学习(1)

    一.git fetch 和git pull 的差别 1.git fetch 相当于是从远程获取最新到本地,不会自动merge,如下指令: git fetch orgin master //将远程仓库的 ...

  3. 文本框、评论框原生js

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  4. SDWC 2018 day5

    望得分:100+100+100 实际得分:100+100+100 Problem 1 晨跑(running.cpp/c/pas)[题目描述]为了响应学校的号召,模范好学生王队长决定晨跑.不过由于种种原 ...

  5. 18/10/19 周五欢乐赛题解(c++版)

    注意本题解并没有去追求最优解,只是用比较暴力的方法求解.D题听说要改说明不是位数30位,目前除了D题可能有问题之外其他代码已经全部正确. A.查找字串 用string BF(暴力求解即可) 代码 #i ...

  6. 二叉堆 及 大根堆的python实现

    Python 二叉堆(binary heap) 二叉堆是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树.二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子 ...

  7. java归并排序

    代码如下: public class MergeSort { public static void mergeSort(DataWrap [] data) { sort(data , 0 , data ...

  8. 《零压力学Python》 之 第三章知识点归纳

    第三章(第一个程序)知识点归纳 编程犹如写剧本.Python函数与剧本差别不大,你可以反复调用函数,而它每次都执行预定的“脚本”(脚本也可以指整个程序). 在Python IDLE中,真正的编程是从编 ...

  9. 《hello-world》第八次团队作业:Alpha冲刺-Scrum Meeting 5

    项目 内容 这个作业属于哪个课程 2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十二 团队作业8:软件测试与Alpha冲刺 团队名称 <hello--worl ...

  10. Django获取当前页面的URL——小记

    获取带参数URL:request.get_all_path() 获取不带参数URL:request.path 获取主机地址:request.get_host()