bzoj3224: Tyvj 1728 普通平衡树 treap

#include<bits/stdc++.h>
#include<set>
#include<cstdio>
#include<iomanip>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define fi first
#define se second
#define PI 3.14159265
//#define ls l,m,rt<<1
//#define rs m+1,r,rt<<1|1
#define eps 1e-7
#define pii pair<int,int>
typedef unsigned long long ull;
const int inf=1e9+1;
const int mx=~0u>>1;
const int mod=1e9+7;
const int maxn=2e5+10;
using namespace std;
struct treap
{
struct node
{
node *ch[2];
int key,siz,wei,cnt;
node(int _key,node * f)
{
ch[0]=ch[1]=f;
key=_key;
siz=cnt=1;
wei=rand();
}
void push(){siz=ch[0]->siz+ch[1]->siz+cnt;}
}*null,*root;
treap()
{
null=new node(0,0);
null->siz=null->cnt=0;null->wei=mx;
root=null;
}
void rot(node *&rt,bool d)//把!d抬上来
{
node *c=rt->ch[!d];
rt->ch[!d]=c->ch[d];
c->ch[d]=rt;
rt->push();c->push();
rt=c;
}
void insert(const int &key,node *&rt)//插入
{
if(rt==null){rt=new node(key,null);return;}
if(key==rt->key)
{
rt->cnt++;
rt->siz++;return ;
}
bool d=key>rt->key;
insert(key,rt->ch[d]);
if(rt->wei>rt->ch[d]->wei)rot(rt,!d);
rt->push();
}
void remove(const int &key,node *&rt)//删除
{
if(rt==null)return;
bool d=key>rt->key;
if(key==rt->key)
{
if(rt->cnt>1){rt->cnt--;rt->siz--;return ;}
d=rt->ch[0]->wei>rt->ch[1]->wei;
if(rt->ch[d]==null)
{
delete rt;
rt=null;
return ;
}
rot(rt,!d);
remove(key,rt);
}
else remove(key,rt->ch[d]);
rt->push();
}
void view(node *rt)
{
if(rt==null)
{
return ;
}
cout<<rt->key<<endl;
view(rt->ch[0]);
view(rt->ch[1]);
}
int rank(const int &key,node *rt)//查询key是第几大
{
if(rt==null)return 0;
if(key==rt->key)return rt->ch[0]->siz+1;
if(key<rt->key)return rank(key,rt->ch[0]);
else return rt->ch[0]->siz+rt->cnt+rank(key,rt->ch[1]);
}
node *select(int k,node *rt)//查询第k大
{
// cout<<k<<endl;
int s=rt->ch[0]->siz+rt->cnt;
if(k>rt->ch[0]->siz&&k<=s)return rt;
if(k>s)return select(k-s,rt->ch[1]);
else return select(k,rt->ch[0]);
//  if(k<s)return select(k-s,rt->ch[1]);
// else return select(k,rt->ch[0]);
}
int pre(const int &k)//返回第一个比k小的树
{
node *t=root;
int ret=0;
while(t!=null)
{
if(t->key<k)ret=t->key,t=t->ch[1];
else t=t->ch[0];
}
return ret;
}
int suc(const int &k)//返回第一个比k大的数
{
node *t=root;
int ret=0;
while(t!=null)
{
if(t->key>k)ret=t->key,t=t->ch[0];
else t=t->ch[1];
}
return ret;
}
};
int main()
{
int n;
treap ac=treap();
scanf("%d",&n);
while(n--)
{
int op,x;
scanf("%d %d",&op,&x);
if(op==1)ac.insert(x,ac.root);
else if(op==2)ac.remove(x,ac.root);
else if(op==3)printf("%d\n",ac.rank(x,ac.root));
else if(op==4)printf("%d\n",ac.select(x,ac.root)->key);
else if(op==5)printf("%d\n",ac.pre(x));
else printf("%d\n",ac.suc(x));
//  ac.view(ac.root);
}
return 0;
}

posted @ 2018-08-03 18:53  lhclqslove  阅读(123)  评论(0编辑  收藏  举报