treap相对splay容易理解

对每个节点x,tr[x].rd=rand();

然后对tr[x].rd操作,使其满足堆性质

#include<bits/stdc++.h>
#define maxn 1000005
#define ls tr[k].l
#define rs tr[k].r
using namespace std;
int n,rt,size;
struct tree{
	int l,r,sz,cnt,rd,v;
}tr[maxn];
inline int ran(){
    static int seed = 2333;
    return seed = (int)((((seed ^ 998244353) + 19260817ll) * 19890604ll) % 1000000007);
}
void update(int k)
{
	tr[k].sz=tr[ls].sz+tr[rs].sz+tr[k].cnt;
}
void lturn(int &k)
{
	int t=rs;rs=tr[t].l;tr[t].l=k;
	tr[t].sz=tr[k].sz;update(k);k=t;
}
void rturn(int &k)
{
	int t=ls;ls=tr[t].r;tr[t].r=k;
	tr[t].sz=tr[k].sz;update(k);k=t;
}
void insert(int &k,int x)
{
	if(k==0)
	{
		++size;k=size;
		tr[k].cnt=tr[k].sz=1;
		tr[k].v=x;
		tr[k].rd=ran();
		return;
	}
	tr[k].sz++;
	if(x==tr[k].v)tr[k].cnt++;
	else if(x<tr[k].v)
	{
		insert(ls,x);
		if(tr[ls].rd<tr[k].rd)rturn(k);
	}
	else 
	{
		insert(rs,x);
		if(tr[rs].rd<tr[k].rd)lturn(k);
	}
}
void del(int &k,int x)
{
	if(k==0)return;
	if(tr[k].v==x)
	{
		if(tr[k].cnt>=2){tr[k].cnt--;tr[k].sz--;return;}
		if(ls==0||rs==0)k=ls+rs;
		else {
			if(tr[ls].rd<tr[rs].rd)rturn(k),del(k,x);
			else lturn(k),del(k,x);
		}
	}
	else if(tr[k].v<x)tr[k].sz--,del(rs,x);
	else tr[k].sz--,del(ls,x);
}
int find_pm(int k,int x)
{
	if(k==0)return 0;
	if(tr[k].v==x)return tr[ls].sz+1;
	if(tr[k].v>x)return find_pm(ls,x);
	else return tr[ls].sz+tr[k].cnt+find_pm(rs,x);
}
int find_wz(int k,int x)
{
	if(k==0)return 0;
	if(x<=tr[ls].sz)return find_wz(ls,x);
	else if(x>tr[ls].sz+tr[k].cnt)return find_wz(rs,x-tr[k].cnt-tr[ls].sz);
	else return tr[k].v;
}
int find_qq(int k,int x)
{
	if(k==0)return -1e9;
	if(tr[k].v<x)return max(tr[k].v,find_qq(rs,x));
	return find_qq(ls,x);
}
int find_hj(int k,int x)
{
	if(k==0)return 1e9;
	if(tr[k].v>x)return min(tr[k].v,find_hj(ls,x));
	return find_hj(rs,x);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int temp,x;
 		scanf("%d%d",&temp,&x);
		if(temp==1)insert(rt,x);
		if(temp==2)del(rt,x);
		if(temp==3)printf("%d\n",find_pm(rt,x));
		if(temp==4)printf("%d\n",find_wz(rt,x));
		if(temp==5)printf("%d\n",find_qq(rt,x));
		if(temp==6)printf("%d\n",find_hj(rt,x));
	}
	return 0;
}

  

posted on 2018-03-09 10:18  geniuschenjj  阅读(109)  评论(1编辑  收藏  举报