码迷,mamicode.com
首页 > 其他好文 > 详细

[知识点]Treap 指针实现

时间:2017-09-24 16:18:07      阅读:170      评论:0      收藏:0      [点我收藏+]

标签: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;
} 

  

[知识点]Treap 指针实现

标签:hup   print   namespace   scanf   而且   原来   treap   include   mes   

原文地址:http://www.cnblogs.com/Hallmeow/p/7587329.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!