tyvj 普通平衡树 SBT or splay
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdio>
using namespace std;
#define MAXT 1000000
#define INF 0x3f3f3f3f
int n,m; struct SBTree
{
int L[MAXT],R[MAXT],K[MAXT],S[MAXT];
queue<int> Q;
int root;
SBTree()
{
root=;
int i;
for (i=;i<MAXT;i++)
{
Q.push(i);
}
}
void update(int &now)
{
S[now]=S[L[now]]+S[R[now]]+;
}
void r_rotate(int &now)
{
int t=L[now];
L[now]=R[t];update(now);
R[t]=now;update(t);
now=t;
}
void l_rotate(int &now)
{
int t=R[now];
R[now]=L[t];update(now);
L[t]=now;update(t);
now=t;
}
void maintain(int &now)
{
if (S[L[L[now]]]>S[R[now]])
{
r_rotate(now);
maintain(L[now]);
maintain(R[now]);
maintain(now);
return;
}
if (S[R[R[now]]]>S[L[now]])
{
l_rotate(now);
maintain(L[now]);
maintain(R[now]);
maintain(now);
return;
}
if (S[L[R[now]]]>S[L[now]])
{
r_rotate(R[now]);
l_rotate(now);
maintain(L[now]);
maintain(R[now]);
maintain(now);
return;
}
if (S[R[L[now]]]>S[R[now]])
{
l_rotate(L[now]);
r_rotate(now);
maintain(L[now]);
maintain(R[now]);
maintain(now);
return;
}
}
void Insert(int &now,int v)
{
if (!now)
{
now=Q.front();
Q.pop();
L[now]=R[now]=;
S[now]=;
K[now]=v;
return ;
}
if (v<=K[now])
{
Insert(L[now],v);
}else
{
Insert(R[now],v);
}
update(now);
maintain(now);
}
void Delete(int &now,int x)
{
// if (!now) throw 1;
if (!now) return ;
if (K[now]==x)
{
if (!L[now]&&!R[now])
{
Q.push(now);
now=;
return ;
}
if (!L[now])
{
Q.push(now);
now=R[now];
return ;
}
if (!R[now])
{
Q.push(now);
now=L[now];
return ;
}
r_rotate(now);
Delete(R[now],x);/**/
update(now);
maintain(now);
return ;
}
if (x<K[now])
{
Delete(L[now],x);
}else
{
Delete(R[now],x);
}
update(now);
maintain(now);
}
int get_val(int &now,int rk)
{
if (rk==S[L[now]]+)
{
return K[now];
}
if (rk<=S[L[now]])
{
return get_val(L[now],rk);
}else
{
return get_val(R[now],rk-S[L[now]]-);
}
}
int get_rank(int &now,int x)
{
if (!now)return INF;
if (x==K[now])
{
return min(S[L[now]]+,get_rank(L[now],x));
}
if (x<K[now])
{
return get_rank(L[now],x);
}else
{
return get_rank(R[now],x)+S[L[now]]+;
}
}
int get_prev(int &now,int v)
{
if (!now)return -INF;
if (K[now]<v)
{
return max(K[now],get_prev(R[now],v));
}else
{
return get_prev(L[now],v);
}
}
int get_next(int &now,int v)
{
if (!now)return INF;
if (K[now]>v)
{
return min(K[now],get_next(L[now],v));
}else
{
return get_next(R[now],v);
}
}
void Scan(int &now)
{
if (!now)return ;
if (S[now]!=S[L[now]]+S[R[now]]+)
{
throw ;
}
Scan(L[now]);
printf("%d ",K[now]);
Scan(R[now]);
}
}SBT;
int main()
{
// freopen("input.txt","r",stdin);
// freopen("output1.txt","w",stdout);
int i,x,opt;
scanf("%d",&m);
for (i=;i<m;i++)
{
scanf("%d%d",&opt,&x);
// cout<<x<<":"<<endl;
switch (opt)
{
case :
SBT.Insert(SBT.root,x);
// SBT.Scan(SBT.root);cout<<endl;
break;
case :
SBT.Delete(SBT.root,x);
// SBT.Scan(SBT.root);cout<<endl;
break;
case :
printf("%d\n",SBT.get_rank(SBT.root,x));
break;
case :
printf("%d\n",SBT.get_val(SBT.root,x));
break;
case :
printf("%d\n",SBT.get_prev(SBT.root,x));
break;
case :
printf("%d\n",SBT.get_next(SBT.root,x));
break;
}
}
return ;
}
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdio>
using namespace std;
#define MAXT 1000000
#define INF 0x3f3f3f3f
struct node
{
int val,cnt,siz;
node* fa,*ch[];
node(){}
node(int a,int b,int c)
{
val=a;cnt=b;siz=c;
}
void update()
{
siz=ch[]->siz+ch[]->siz+cnt;
}
};
node nil_node(,,),*nil=&nil_node;
struct Splay_tree
{
node *root;
int ncnt;
node E[MAXT];
queue<int> Q;
Splay_tree()
{
root=nil;
ncnt=;
int i;
for (i=;i<MAXT;i++)
{
Q.push(i);
}
}
node* new_node(int key)
{
int now=Q.front();
Q.pop();
E[now].val=key;
E[now].cnt=E[now].siz=;
E[now].ch[]=E[now].ch[]=nil;
return &E[now];
}
void rotate(node *now,int pp)
{
node *y=now->fa;
y->ch[!pp]=now->ch[pp];
if (now->ch[pp]!=nil)now->ch[pp]->fa=y;
now->fa=y->fa;
if (y->fa!=nil)/**/
{
if (y->fa->ch[]==y)
{
y->fa->ch[]=now;
}else
{
y->fa->ch[]=now;
}
}
y->fa=now;
now->ch[pp]=y;
y->update();
now->update();/**/
}
void Splay(node* now,node *top)
{
if (now==top||now==nil)return;
node *y;
while (now->fa!=top)
{
y=now->fa;
if (now==y->ch[])
{
if (y->fa!=top&&y==y->fa->ch[])rotate(now,);
rotate(now,);
}else
{
if (y->fa!=top&&y==y->fa->ch[])rotate(now,);
rotate(now,);
}
}
if (top==nil)
{
root=now;
}
}
void Insert(int key)
{
node* now,*x;
now=root;
if (root==nil)
{
root=new_node(key);
x=root;
root->fa=nil;
return ;
}
while()
{
now->siz++;
if (now->val==key)
{
x=now;/**/
now->cnt++;
break;
}
if (key<now->val)
{
if (now->ch[]==nil)
{
now->ch[]=new_node(key);
now->ch[]->fa=now;
x=now->ch[];
break;
}else
{
now=now->ch[];
continue;
}
}
if (key>now->val)
{
if (now->ch[]==nil)
{
now->ch[]=new_node(key);
now->ch[]->fa=now;
x=now->ch[];
break;
}else
{
now=now->ch[];
continue;
}
}
}
Splay(x,nil);
}
void Delete(node *now)
{
if (now==nil)
{
throw "fuck";
}
if (now->cnt>)
{
now->siz--;
now->cnt--;
while (now!=root)
{
now=now->fa;
now->siz--;
}
return ;
}
Splay(now,nil);
if (now->ch[]==nil)
{
root=now->ch[];
now->ch[]->fa=nil;
return ;
}
if (now->ch[]==nil)
{
root=now->ch[];
now->ch[]->fa=nil;
return ;
}
Splay(get_min(now->ch[]),root);
Splay(get_min(now->ch[]),root);
now->ch[]->ch[]=now->ch[];
now->ch[]->fa=now->ch[];
now->ch[]->fa=nil;
root=now->ch[];
root->update();
}
node* get_min(node* now)
{
if (now==nil)return now;
while (now->ch[]!=nil)now=now->ch[];
return now;
}
node *search(int key)
{
node *now;
now=root;
while ()
{
if (now->val==key)
{
return now;
}
if (key<now->val)
{
now=now->ch[];
}else
{
now=now->ch[];
}
}
return nil;
}
int get_rank(int key)
{
Splay(search(key),nil);
return root->ch[]->siz+;
}
int get_val(node *now,int rank)
{
if (rank<=now->ch[]->siz)
{
return get_val(now->ch[],rank);
}
if (rank>now->ch[]->siz+now->cnt)
{
return get_val(now->ch[],rank-now->ch[]->siz-now->cnt);
}
return now->val;
}
int prev(node *now,int key)
{
int ret=-INF;
if (now==nil)return -INF;
if (key>now->val)
{
return max(prev(now->ch[],key),now->val);
}
if (key<=now->val)
{
return prev(now->ch[],key);
}
}
int next(node *now,int key)
{
if (now==nil)return INF;
if (key<now->val)
{
return min(next(now->ch[],key),now->val);
}
if (key>=now->val)
{
return next(now->ch[],key);
}
}
void Scan(node* now)
{
if (now==nil)
{
return ;
}
if (now->ch[]!=nil && now->ch[]->fa!=now)cout<<"Error_a";
if (now->ch[]!=nil && now->ch[]->fa!=now)cout<< "Error_b";
if (now->siz!=now->ch[]->siz+now->ch[]->siz+now->cnt)cout<<"Error_c";
Scan(now->ch[]);
printf("%d[%d] ",now->val,now->cnt);
Scan(now->ch[]);
}
}spt;
int n,m;
int main()
{
// freopen("input.txt","r",stdin);
// freopen("output1.txt","w",stdout);
int i,x,opt;
scanf("%d",&m);
for (i=;i<m;i++)
{
scanf("%d%d",&opt,&x);
switch (opt)
{
case :
spt.Insert(x);
break;
case :
spt.Delete(spt.search(x));
break;
case :
printf("%d\n",spt.get_rank(x));
break;
case :
printf("%d\n",spt.get_val(spt.root,x));
break;
case :
printf("%d\n",spt.prev(spt.root,x));
break;
case :
printf("%d\n",spt.next(spt.root,x));
break;
}
// spt.Scan(spt.root);cout<<endl;
}
return ;
}
tyvj 普通平衡树 SBT or splay的更多相关文章
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- 平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】
平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是 ...
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- 三大平衡树(Treap + Splay + SBT)总结+模板
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)
(其实今天好热啊? 题目大意:插入,删除,k小,前驱后继,数的排名. splay和treap裸题...过几天补个treap的 splay: #include<iostream> #incl ...
- bzoj3223 文艺平衡树 (treap or splay分裂+合并)
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 3313 Solved: 1883 [Submit][S ...
- 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2271 Solved: 935[Submit][Stat ...
- 【模板】平衡树——Treap和Splay
二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...
- 平衡树模板【splay的实现】
[平衡树splay实现] 无注释代码 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=1e ...
随机推荐
- JAVA的程序代码小细节,变量的使用,以及一些细节的面试题
package cn.hncu; public class LableDemo { public static void main(String[] args) { //demo1(); demo2( ...
- ubuntu14.04使用root用户登录桌面 分类: 学习笔记 linux ubuntu 2015-07-05 10:30 199人阅读 评论(0) 收藏
ubuntu安装好之后,默认是不能用root用户登录桌面的,只能使用普通用户或者访客登录.怎样开启root用户登录桌面呢? 先用普通用户登录,然后切换到root用户,然后执行如下命令: vi /usr ...
- Java基础知识强化之IO流笔记26:FileInputStream / FileOutputStream 复制mp4视频的案例
1. 需求:把D:\\English.mp4 复制到当前项目目录下copy.mp4 代码示例: package com.himi.filecopy; import java.io.FileInput ...
- CSS背景颜色、背景图片、平铺、定位、固定
CSS背景颜色设置 background-color:red;如设置背景颜色为红色: 背景颜色设置支持3种写法: 颜色名 16进制 rgb CSS背景图片颜色设置 background-image:u ...
- apache源码编译安装详解
查看是否安装 rpm -qa httpd 如果已安装,则卸载:rpm -e 卸载 --nodeps 不考虑意外 下载 wget http://mirrors.sohu.c ...
- Oracle常用几种Sql用法
前几天客户提出一个月报,经过了解需求及公式等过程长达20小时,总算基本模型出来了,贴出来啥晒,对于我这种菜鸟来说也算小有提高,虽然Sql语句不是很庞大,但是里面涉及到了几种算法,个人觉得还是经常能用到 ...
- IIS 上发布ASP.NET5
原文 http://docs.asp.net/en/latest/publishing/iis.html 1.安装HTTP Platform Handler ,这个是必需的,不然无法通过IIS访问AS ...
- 一道JS addEventListener面试题
在园里看到一道面试题,<div id="test">Click Here</div> var node=document.getElementById('t ...
- .NET多线程同步方法详解
.NET多线程同步方法详解(一):自由锁(InterLocked) .NET多线程同步方法详解(二):互斥锁(lock) NET多线程同步方法详解(三):读写锁(ReadWriteLock) .NET ...
- ORACLE如何停止一个JOB
ORACLE如何停止一个JOB1 相关表.视图2 问题描述为同事解决一个因为网络连接情况不佳时,执行一个超长时间的SQL插入操作.既然网络状况不好,就选择了使用一次性使用JOB来完成该插入操作.在JO ...