平衡树:treap学习笔记(2)
来源:互联网 发布:db2导入数据库命令 编辑:程序博客网 时间:2024/06/04 22:48
上一次写了旋转的treap(代码非常简单。
这次我们来写无旋的treap。这个treap没有旋转操作。
有两个基本操作:合并、分裂。
插入和删除时都使用到了这两个操作,感觉很妙呀qaq。
具体的解释详见:https://wenku.baidu.com/view/09fbf8147c1cfad6195fa7f0.html;
还有zcy的代码:https://www.cnblogs.com/zcysky/p/6876646.html
还有http://blog.csdn.net/wyj_jenny/article/details/78559603;
#include<bits/stdc++.h>using namespace std;#define ll long long#define mp make_pairtypedef pair<int,int>par;const int MAXN=1e5;const int INF=1e9;int rt=0,cnt=0;struct treap{ int lson[MAXN],rson[MAXN],size[MAXN],prio[MAXN],w[MAXN]; inline void pushup(int p){size[p]=size[lson[p]]+size[rson[p]]+1;} par split(int p,int x){ if(!x)return mp(0,p); int l=lson[p],r=rson[p]; if(x<=size[l]){//下面千万别打错。 par tem=split(l,x); lson[p]=tem.second;pushup(p);return mp(tem.first,p); } par tem=split(r,x-size[l]-1); rson[p]=tem.first;pushup(p);return mp(p,tem.second); } int merge(int x,int y){ if(!x){ pushup(y);return y; } if(!y){ pushup(x);return x; } if(prio[x]<prio[y]){ rson[x]=merge(rson[x],y);pushup(x);return x; } else { lson[y]=merge(x,lson[y]);pushup(y);return y; } } int queryrank(int p,int x){ int ans=0,tem=INF; while(p){//p的转换,顺序别打反。 if(x==w[p])tem=min(tem,ans+size[lson[p]]+1); if(x>w[p])ans+=size[lson[p]]+1,p=rson[p]; else p=lson[p]; } return tem==INF?ans:tem; } void insert(int x){ int k=queryrank(rt,x);par tem=split(rt,k); w[++cnt]=x;prio[cnt]=rand();size[cnt]=1; rt=merge(tem.first,cnt);rt=merge(rt,tem.second); } void del(int x){ int k=queryrank(rt,x);par t1=split(rt,k),t2=split(t1.first,k-1); rt=merge(t2.first,t1.second); } int findnum(int p,int x){ for(;;){ if(x==size[lson[p]]+1)return w[p]; if(x<size[lson[p]]+1)p=lson[p]; else x=x-size[lson[p]]-1,p=rson[p]; } } int findpre(int p,int x){ int ans=-INF; while(p){ if(x>w[p]){ ans=max(ans,w[p]); p=rson[p]; } else p=lson[p]; } return ans; } int findsub(int p,int x){ int ans=INF; while(p){ if(x<w[p]){ ans=min(ans,w[p]); p=lson[p]; } else p=rson[p]; } return ans; }}treap;int main(){ int n,opt,x; scanf("%d",&n);srand(82602002); for(int i=1;i<=n;i++){ scanf("%d%d",&opt,&x); if(opt==1)treap.insert(x); if(opt==2)treap.del(x); if(opt==3)printf("%d\n",treap.queryrank(rt,x)); if(opt==4)printf("%d\n",treap.findnum(rt,x)); if(opt==5)printf("%d\n",treap.findpre(rt,x)); if(opt==6)printf("%d\n",treap.findsub(rt,x)); } return 0;}
阅读全文
0 0
- 平衡树:treap学习笔记(2)
- 平衡树(treap)学习笔记
- 平衡树:treap学习笔记(1)
- 平衡树:treap学习笔记(3)
- 【学习】Treap平衡树
- 平衡树学习笔记——旋转式treap
- 随机二叉平衡树treap学习
- TREAP平衡树代码
- Treap平衡树
- Treap平衡树
- Treap平衡树
- Treap平衡树
- TREAP平衡树
- 平衡树Treap模版
- 【平衡树】Treap
- 平衡树Treap
- 平衡树之treap
- 普通平衡树 treap
- java相关知识
- js\jquery基础知识(一)
- 解决网页刷新时布局紊乱(jquery ready和load事件)
- springmvc获取resquest/response
- vue-router获取上一页面的url信息
- 平衡树:treap学习笔记(2)
- DataBinding框架学习
- 【银行】2016年中国银行信息科技岗 笔试+面试经验汇总
- 深度克隆
- 微信开放平台开发——网页微信扫码登录(OAuth2.0)
- PCIE 关于BAR的相关学习
- mac如何导出cer私钥
- c++之函数模板
- 在table里动态获取tr里的所有数据