fhq-treap,也即非旋treap,可以在不进行旋转操作的前提下维护treap。由于不需要旋转,可以对其可持久化。

  fhq-treap的基本操作是merge和split,并且通过这两个操作实现对treap的各项维护。

  merge用来合并两棵treap,且要求满足其中一棵treap中的最大值小于另一棵treap中的最小值。实现方式类似于左偏树,即每次考虑合并以x为根和以y为根的子树(不妨令x子树中的值较小)。因为要维持treap自身的性质,合并后应该以x和y中优先级较高的为根。如果x优先级较高,继续将x的右子树与y合并,再将所得子树作为x的右子树;如果y优先级较高,继续将y的左子树与x合并,再将所得子树作为y的左子树。这里就可以进行可持久化。因为树高是期望log的,合并复杂度即为log。

  split用来将一棵treap分裂为两棵,且分裂后使得前k小的作为一棵treap,剩下的作为另一棵。具体地,分裂以x为根的子树时,考虑前k小的所处位置。如果左子树大小恰好为k,分裂后直接退出;如果左子树大小>k,显然应该进入左子树继续操作,分裂后返回两棵treap的根,其中一棵接到已分裂好的原treap上。另一种情况类似。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 500010
#define inf 2147483647
#define pii pair<int,int>
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,root[N],cnt;
struct data{int ch[],x,p,s;
}tree[N<<];
void up(int k){tree[k].s=tree[lson].s+tree[rson].s+;}
int qnum(int k,int x)
{
if (tree[lson].s+==x) return tree[k].x;
if (tree[lson].s+>x) return qnum(lson,x);
else return qnum(rson,x-tree[lson].s-);
}
int qrank(int k,int x)
{
if (!k) return ;
if (tree[k].x>=x) return qrank(lson,x);
else return tree[lson].s++qrank(rson,x);
}
int qpre(int k,int x)
{
if (!k) return -inf;
if (tree[k].x>=x) return qpre(lson,x);
else return max(tree[k].x,qpre(rson,x));
}
int qsuf(int k,int x)
{
if (!k) return inf;
if (tree[k].x<=x) return qsuf(rson,x);
else return min(tree[k].x,qsuf(lson,x));
}
int merge(int x,int y)
{
if (!x||!y) return x|y;
int k=++cnt;
if (tree[x].p>tree[y].p)
{
tree[k]=tree[x];
rson=merge(rson,y);
}
else
{
tree[k]=tree[y];
lson=merge(x,lson);
}
up(k);
return k;
}
pii split(int k,int x)
{
if (!k) return make_pair(,);
int u=++cnt;tree[u]=tree[k];
if (tree[tree[u].ch[]].s==x) return tree[u].ch[]=,up(u),make_pair(lson,u);
if (tree[tree[u].ch[]].s>x)
{
pii v=split(tree[u].ch[],x);
return tree[u].ch[]=v.second,up(u),make_pair(v.first,u);
}
else
{
pii v=split(tree[u].ch[],x-tree[tree[u].ch[]].s-);
return tree[u].ch[]=v.first,up(u),make_pair(u,v.second);
}
}
int newpoint(int x)
{
cnt++;tree[cnt].x=x,tree[cnt].p=rand(),tree[cnt].s=,tree[cnt].ch[]=tree[cnt].ch[]=;
return cnt;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("fhqtreap.in","r",stdin);
freopen("fhqtreap.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
srand();
m=read();
for (int i=;i<=m;i++)
{
int last=read(),op=read(),x=read();
root[i]=root[last];
switch (op)
{
case :
{
int u=qrank(root[i],x),v=newpoint(x);
pii p=split(root[i],u);
root[i]=merge(merge(p.first,v),p.second);
break;
}
case :
{
int p=qrank(root[i],x);
if (qnum(root[i],p+)==x)
{
pii u=split(root[i],p),v=split(u.second,);
root[i]=merge(u.first,v.second);
}
break;
}
case :
{
printf("%d\n",qrank(root[i],x)+);
break;
}
case :
{
printf("%d\n",qnum(root[i],x));
break;
}
case :
{
printf("%d\n",qpre(root[i],x));
break;
}
case :
{
printf("%d\n",qsuf(root[i],x));
break;
}
}
//for (int j=1;j<=m;j++) cout<<root[j]<<' ';cout<<endl;
//for (int j=1;j<=cnt;j++) cout<<tree[j].x<<' '<<tree[j].s<<' '<<tree[j].ch[0]<<' '<<tree[j].ch[1]<<endl;cout<<endl;
}
return ;
}

Luogu3835 【模板】可持久化平衡树(fhq-treap)的更多相关文章

  1. 洛谷.3835.[模板]可持久化平衡树(fhq treap)

    题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上 ...

  2. Luogu P3835 【模板】可持久化平衡树(fhq Treap)

    P3835 [模板]可持久化平衡树 题意 题目背景 本题为题目普通平衡树的可持久化加强版. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本 ...

  3. P3391 【模板】文艺平衡树FHQ treap

    P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转 ...

  4. 2021.12.08 平衡树——FHQ Treap

    2021.12.08 平衡树--FHQ Treap http://www.yhzq-blog.cc/fhqtreapzongjie/ https://www.cnblogs.com/zwfymqz/p ...

  5. 洛谷P3369 【模板】普通平衡树(Treap/SBT)

    洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...

  6. [luogu P3369]【模板】普通平衡树(Treap/SBT)

    [luogu P3369][模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删 ...

  7. AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369

    [模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...

  8. 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline _ ...

  9. 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...

  10. 红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 近几天闲来无事...就把各种平衡树都写了一下... 下面是红黑树(Red Black Tree) 喜闻乐见拿到了luo ...

随机推荐

  1. Centos7下完美安装并配置mysql5.6

    Centos7将默认数据库mysql替换成了Mariadb,对于我们这些还想用mysql的人来说并不是一个好消息. 最近我搜罗了网上各种安装教程,各种出问题,要么安装失败,要么安装成功了却使用不了my ...

  2. IDEA 创建和使用tomcat

    一.创建一个普通web项目,步骤略,如下图. 二.配置项目相关信息. 1.通过如下方式在Artifacts下添加我们的项目. 2.选中我们的项目. 3.修改项目的默认输出位置,可根据需要修改. 4.如 ...

  3. char.IsLetter的使用

    先看一下下面的代码,大家会觉得控制台输出什么? 输出:Chiantxt  .对吗? 因为你看到char.IsLetter这个方法的文字的注释是这样写的: 但实际上输出的结果是这样的: ??? 怎么还输 ...

  4. arm那些事

    ARM简介 ARM的商业模式: ARM只负责设计IC,并且出卖自己的设计IP(版权). ARM自己不生产芯片,而是把设计IP授权给其他半导体厂商来生产芯片. 严格地说,ARM并不是一家半导体厂商.   ...

  5. EF Core中DbContext可以被Dispose多次

    我们知道,在EF Core中DbContext用完后要记得调用Dispose方法释放资源.但是其实DbContext可以多次调用Dispose方法,虽然只有第一次Dispose会起作用,但是DbCon ...

  6. Luogu3877 TJOI2010 打扫房间 二分图、网络流

    传送门 真是菜死了模板题都不会-- 首先\(30 \times 30\)并不能插头DP,但是范围仍然很小所以考虑网络流. 注意每个点都要包含在一个回路中,那么每一个点的度数都必须为\(2\),也就是说 ...

  7. EZ 2018 06 10 NOIP2018 模拟赛(十八)

    好久没写blog&&比赛题解了,最近补一下 这次还是很狗的,T3想了很久最后竟然连并查集都忘写了,然后T2map莫名爆炸. Rating爆减......链接不解释 好了我们开始看题. ...

  8. 记一次MongoDB裸奔

    导言 大意失荆州,裸奔的 MongoDB 被黑了.虽然并不是什么非常重要的数据,但也给自己敲响的一个警钟.虽然我们平时不容易接触到数据安全,但我们在开发,部署项目的时候,一定要养成良好的安全意识. 根 ...

  9. item 11: 比起private undefined function优先使用deleted function

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果你为其他开发者提供代码,并且你想阻止他们调用一个特定的函数,你 ...

  10. 【Beta阶段】第十次Scrum Meeting!!!

    每日任务内容: 本次会议为第十次Scrum Meeting会议~ 本次会议为团队Beta阶段的最后一次会议!! 队员 今日完成任务 刘乾 #136(完成一半,今晨发布) 团队博客撰写 https:// ...