您的位置:首页 > 其它

bzoj3224 treap模版

2015-06-18 10:22 239 查看
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define clr(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define mkp(a,b) make_pair(a,b)
int read(){
int ans=0,f=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
ans=ans*10+c-'0';
c=getchar();
}
return ans*f;
}
const int maxn=500009,inf=0x3fffffff;
struct node{
int s,v,r;
node*ch[2];
inline void maintain(){
s=ch[0]->s+ch[1]->s+1;
}
}pool[maxn<<2],*root,*pt=pool,*null;
int n;
node*newnode(int x){
pt->s=1;pt->ch[0]=pt->ch[1]=null;
pt->r=rand()*rand();
pt->v=x;
return pt++;
}
void rot(node*&o,int d){
node*t=o->ch[d^1];
o->ch[d^1]=t->ch[d];t->ch[d]=o;
o->maintain();t->maintain();
o=t;
}
void insert(node*&o,int x){
if(o==null) o=newnode(x);
else{
if(x<o->v){
insert(o->ch[0],x);
if(o->ch[0]->r>o->r) rot(o,1);
}else{
insert(o->ch[1],x);
if(o->ch[1]->r>o->r) rot(o,0);
}
}
o->maintain();
}
void del(node*&o,int x){
if(o->v==x){
if(o->ch[0]!=null&&o->ch[1]!=null){
if(o->ch[0]->r>o->ch[1]->r){
rot(o,1);del(o->ch[1],x);
}else{
rot(o,0);del(o->ch[0],x);
}
}else if(o->ch[0]!=null) o=o->ch[0];
else o=o->ch[1];
}else{
if(x<o->v) del(o->ch[0],x);
else del(o->ch[1],x);
}
if(o!=null) o->maintain();
}
int rank(node*o,int x){
if(o==null) return inf;
if(x==o->v)    return min(rank(o->ch[0],x),o->ch[0]->s+1);
if(x<o->v) return rank(o->ch[0],x);
return rank(o->ch[1],x)+o->ch[0]->s+1;
}
int num(node*o,int x){
if(x==o->ch[0]->s+1) return o->v;
if(x<=o->ch[0]->s) return num(o->ch[0],x);
return num(o->ch[1],x-o->ch[0]->s-1);
}
int pre(node*o,int x){
if(o==null) return -1;
return x<=o->v?pre(o->ch[0],x):max(o->v,pre(o->ch[1],x));
}
int suc(node*o,int x){
if(o==null) return inf;
return x>=o->v?suc(o->ch[1],x):min(o->v,suc(o->ch[0],x));
}
void init(){
null=newnode(0);
null->s=null->r=0;
root=null;
}
int main(){
init();
n=read();
rep(i,1,n){
int opt=read(),x=read();
if(opt==1) insert(root,x);
else if(opt==2) del(root,x);
else if(opt==3) printf("%d\n",rank(root,x));
else if(opt==4) printf("%d\n",num(root,x));
else if(opt==5) printf("%d\n",pre(root,x));
else printf("%d\n",suc(root,x));
}
return 0;
}


View Code

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 3847 Solved: 1575
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10

1 106465

4 1

1 317721

1 460929

1 644985

1 84185

1 89851

6 81968

1 492737

5 493598

Sample Output

106465

84185

492737

HINT

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]

Source

平衡树

[Submit][Status][Discuss]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: