bzoj3224普通平衡树 Splay
来源:互联网 发布:阿里云域名备案 编辑:程序博客网 时间:2024/05/08 13:40
第一次写Splay 憋了一天累觉不爱
网上关于Splay的资料太少了- -||
http://www.cnblogs.com/kuangbin/archive/2013/04/21/3034081.html
先贴 有空填坑
Splay的基本操作是rotate 左旋右旋
基于此的是splay 将一个点旋转到根节点 也正是因此(?) 它的复杂度均摊logn
insert操作 从根往下找知道找到叶子节点 插入 splay到根
delete操作 方法众多? 将它的前一名splay到根 它的后一名splay到根的右节点 它就在根的右节点的左节点 这也是提取一断区间的方法
split(a,k) 将第k名旋转到跟 右侧断开
merge(s1,s2) 将s1中最大元素旋转到根 根的右子树=s2
merge可以理解为两个序列的合并 两个序列的权值并不满足平衡树 或者根本不存在权值 我们是假设有那么一个权值 即代表它在序列里的位置 平衡树的中序遍历就是这个序列
区间操作:懒标记
和线段树大同小异 提取区间[a,b]:将a-1旋转到根 b+1旋转到根的右节点
区间反转:懒标记
#include<iostream>#include<cstdio>#define N 100005#define inf 1<<30using namespace std;struct Node{int ls,rs,fa,sz,val;}t[N];int n,num=0,root=0;void upd(int k){t[k].sz=t[t[k].ls].sz+t[t[k].rs].sz+1;}void rot(int x,int d){ int y=t[x].fa,z=t[y].fa; if(d==1){ t[y].ls=t[x].rs;t[t[x].rs].fa=y; t[x].rs=y;t[y].fa=x; t[x].fa=z; if(t[z].ls==y) t[z].ls=x; if(t[z].rs==y) t[z].rs=x; upd(y);upd(x); } if(d==0){ t[y].rs=t[x].ls;t[t[x].ls].fa=y; t[x].ls=y;t[y].fa=x; t[x].fa=z; if(t[z].rs==y) t[z].rs=x; if(t[z].ls==y) t[z].ls=x; upd(y);upd(x); }}void splay(int x,int f){ while(t[x].fa!=f){ int y=t[x].fa,z=t[y].fa; if(z==f&&t[y].ls==x) rot(x,1); else if(z==f&&t[y].rs==x) rot(x,0); else if(t[z].ls==y&&t[y].ls==x) rot(y,1),rot(x,1); else if(t[z].rs==y&&t[y].rs==x) rot(y,0),rot(x,0); else if(t[z].ls==y&&t[y].rs==x) rot(x,0),rot(x,1); else if(t[z].rs==y&&t[y].ls==x) rot(x,1),rot(x,0); }}void newnode(int x){t[++num].sz=1;t[num].val=x;}int Rank(int x,int k){ int tmp=inf,ans=0; while(k){ if(t[k].val==x) tmp=min(tmp,ans+t[t[k].ls].sz+1); if(t[k].val<x) ans+=t[t[k].ls].sz+1,k=t[k].rs; else k=t[k].ls; } return tmp==inf?ans:tmp;}int xth(int x,int k){ while(1){ if(t[t[k].ls].sz==x-1) return t[k].val; if(t[t[k].ls].sz<x-1) x-=(t[t[k].ls].sz+1),k=t[k].rs; else k=t[k].ls; }}int pre(int x,int k){ int ans=-inf; while(k){ if(t[k].val<x) ans=max(ans,t[k].val),k=t[k].rs; else k=t[k].ls; } return ans;}int suc(int x,int k){ int ans=inf; while(k){ if(t[k].val>x) ans=min(ans,t[k].val),k=t[k].ls; else k=t[k].rs; } return ans;}void ins(int x,int k){ if(t[k].val<x){ if(t[k].rs==0) newnode(x),t[k].rs=num,t[num].fa=k,splay(num,0),root=num; else ins(x,t[k].rs),upd(k); } else{ if(t[k].ls==0) newnode(x),t[k].ls=num,t[num].fa=k,splay(num,0),root=num; else ins(x,t[k].ls),upd(k); }}int getk(int now,int k){ int wtf=t[t[now].ls].sz+1; if(wtf==k) return now; if(wtf<k) return getk(t[now].rs,k-wtf); else return getk(t[now].ls,k);}void del(int x){ int k=Rank(x,root); int n1=getk(root,k-1); splay(n1,0);root=n1; splay(getk(root,k+1),root); t[t[root].rs].ls=0;}int main(){ freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); scanf("%d",&n); ins(-inf,root); ins(inf,root); while(n--){ int opt,x; scanf("%d%d",&opt,&x); if(opt==1) ins(x,root); if(opt==2) del(x); if(opt==3) printf("%d\n",Rank(x,root)-1); if(opt==4) printf("%d\n",xth(x+1,root)); if(opt==5) printf("%d\n",pre(x,root)); if(opt==6) printf("%d\n",suc(x,root)); } return 0;}
0 0
- bzoj3224普通平衡树 Splay
- [BZOJ3224] 普通平衡树 - splay
- BZOJ3224 普通平衡树(splay)
- [BZOJ3224][SPLAY]普通平衡树
- [BZOJ3224]普通平衡树 SPlay
- bzoj3224普通平衡树splay
- BZOJ3224 普通平衡树 Splay + 替罪羊树
- BZOJ3224普通平衡树splay,SBT代码
- 【BZOJ3224】 【CODEVS4543】 普通平衡树 splay
- bzoj3224 普通平衡树【splay版】
- 【bzoj3224】【Tyvj1728】【普通平衡树】【splay】
- 【bzoj3224】普通平衡树(splay板子)
- bzoj3224 普通平衡树 splay模板题
- 平衡树之splay BZOJ3224 普通平衡树
- BZOJ3224:普通平衡树(含SBT、Treap、Splay模板)
- 【模板】【bzoj3224】Tyvj 1728 普通平衡树 Splay
- 【BZOJ3224】【codevs4543】【tyvj1728】普通平衡树,第一次的splay
- BZOJ3224+洛谷3369普通平衡树 splay版
- mycat ShareJoin后少了2条记录的问题剖析详细过程
- 第三届河南省大学生程序设计竞赛题型简要分析
- HDU 1395 2^x mod n = 1(快速幂取模)
- 技术周报 Gif图片 LoadingView
- js 实现数字的进制转换
- bzoj3224普通平衡树 Splay
- ubuntu网络
- Java学习笔记之继承和接口(一) super关键字、final关键字、abstract类和方法
- 图说HashMap多线程并发问题分析
- 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解
- 安装java和hadoop的过程以及配置环境变量
- iOS开发 CoreMotion 获取当前运动状态 步行/跑步/自行车/驾车 CMMotionActivityManager
- Android:使用MuPdf开源库阅读PDF文件
- TCP/IP——TCP协议中提高网络利用率的机制