标签:hup print namespace scanf 而且 原来 treap include mes
其实平衡树这个东东,我原来也是打过那么几遍的,而且三种基本的都打过了。但是呢,当时内心抵触指针,于是就用的网上的数组平衡树模板
理解起来倒是没什么问题,无奈码量略大T_T
然后就有一段时间没打平衡树了。这两天刷数据结构专题,发现一道 [HNOI 2012]永无乡 需要建多颗平衡树。
我靠!这是对我的数组平衡树的毁灭性的打击啊!!
于是狠了狠心,学指针打法!
然后hww神牛为我提供了他的板子。照着打了不到一个小时,发现指针实现的话,码量灰常小的,而且也很好理解的!
于是乎我现在满心欢喜。不过悲催的是我的splay还是用数组实现的T_T。找个机会把splay也改成指针打法。
嗯。先把Treap搞定了。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define N 101000
#include<cstdlib>
#define size(x) ((x)?(x->size):(0))
#define ls(x) (x->ch[0])
#define rs(x) (x->ch[1])
int n;
struct Treap{
int size,v,key;
Treap *ch[2];
Treap(int x=0){
v=x;size=1;key=rand();ch[0]=ch[1]=NULL;
}
}*root;
void pushup(Treap *rt){
rt->size=size(ls(rt))+size(rs(rt))+1;
}
void turn(Treap *&rt,int d){
Treap *t=rt->ch[d^1];
rt->ch[d^1]=t->ch[d];pushup(rt);
t->ch[d]=rt;pushup(t);
rt=t;
}
void insert(Treap *&rt,int x){
if(!rt){
rt=new Treap(x);return;
}
int d=x < rt->v;
insert(rt->ch[d^1],x);
pushup(rt);
if(rt->ch[d^1]->key < rt->key) turn(rt,d);
}
void del(Treap *&rt,int x){
if(rt->v==x){
if(ls(rt)&&rs(rt)){
int d=ls(rt)->key < rs(rt)->key;
turn(rt,d);del(rt->ch[d],x);
}
else{
Treap *t=NULL;
if(ls(rt)) t=ls(rt);
else t=rs(rt);
delete rt;rt=t;
}
}
else{
int d=x < rt->v;
del(rt->ch[d^1],x);
}
if(rt) pushup(rt);
}
int Rank(int x){
Treap *rt=root;
int ans(0);
while(rt){
if(x > rt->v){
ans+=size(ls(rt))+1;
rt=rs(rt);
}
else rt=ls(rt);
}
return ans;
}
int kth(int k){
Treap *rt=root;
while(rt){
if(size(ls(rt))+1==k) return rt->v;
if(size(ls(rt))+1>k) rt=ls(rt);
else{
k-=size(ls(rt))+1;rt=rs(rt);
}
}
return 0;
}
int main(){
scanf("%d",&n);
pos(i,1,n){
int opt,x;
scanf("%d%d",&opt,&x);
if(opt==1)
insert(root,x);
else if(opt==2)
del(root,x);
else if(opt==3)
printf("%d\n",Rank(x)+1);
else if(opt==4)
printf("%d\n",kth(x));
else if(opt==5)
printf("%d\n",kth(Rank(x)));
else if(opt==6)
printf("%d\n",kth(Rank(x+1)+1));
}
return 0;
}
标签:hup print namespace scanf 而且 原来 treap include mes
原文地址:http://www.cnblogs.com/Hallmeow/p/7587329.html