treap

太感动了这个博主居然还在更新

hwl的指导下我终于写出了treap!各种意义上都很值得流泪

我太菜了所以我不想讲原理

yang_yulei这篇超好

左儿子变成根是右旋转,右儿子变成根是左旋转

就很傻啊这样命名

旋转后要先update(k),这个k是旧的父亲,再k=t

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
using namespace std;
#define update(k) tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w

struct data
{
	int l;
	int r;
	int v;
	int size;
	int rnd;
	int w;
}tr[100001];
int n,opt,x,size,root,ans;

inline void rturn(int &k)
{
	int t=tr[k].l;
	tr[k].l=tr[t].r;
	tr[t].r=k;
	tr[t].size=tr[k].size;
	update(k);
	k=t;
}

inline void lturn(int &k)
{
	int t=tr[k].r;
	tr[k].r=tr[t].l;
	tr[t].l=k;
	tr[t].size=tr[k].size;
	update(k);
	k=t;
}

void insert(int &k,int x)
{
	if(!k)
	{
		k=++size;
		tr[k].size=tr[k].w=1;
		tr[k].v=x;
		tr[k].rnd=rand();
		return ;
	}
	tr[k].size++;
	if(tr[k].v==x)
		tr[k].w++;
	else if(x>tr[k].v)
	{
		insert(tr[k].r,x);
		if(tr[tr[k].r].rnd<tr[k].rnd)
			lturn(k);
	}
	else
	{
		insert(tr[k].l,x);
		if(tr[tr[k].l].rnd<tr[k].rnd)
			rturn(k);
	}
}

void del(int &k,int x)
{
	if(!k)
		return ;
	if(tr[k].v==x)
	{
		if(tr[k].w>1)
		{
			tr[k].w--;
			tr[k].size--;
			return ;
		}
		if(tr[k].l*tr[k].r==0)
			k=tr[k].l+tr[k].r;
		else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd)
			rturn(k),del(k,x);
		else
			lturn(k),del(k,x);
	}
	else if(x>tr[k].v)
		tr[k].size--,del(tr[k].r,x);
	else
		tr[k].size--,del(tr[k].l,x);
}

int query_rank(int k,int x)
{
	if(!k)
		return 0;
	if(tr[k].v==x)
		return tr[tr[k].l].size+1;
	else if(x>tr[k].v)
		return tr[tr[k].l].size+tr[k].w+query_rank(tr[k].r,x);
	else
		return query_rank(tr[k].l,x);
}

int query_num(int k,int x)
{
	if(!k)
		return 0;
	if(x<=tr[tr[k].l].size)
		return query_num(tr[k].l,x);
	else if(x>tr[tr[k].l].size+tr[k].w)
		return query_num(tr[k].r,x-tr[tr[k].l].size-tr[k].w);
	else
		return tr[k].v;
}

void query_pro(int k,int x)
{
	if(!k)
		return ;
	if(tr[k].v<x)
		ans=tr[k].v,query_pro(tr[k].r,x);
	else
		query_pro(tr[k].l,x);
}

void query_sub(int k,int x)
{
	if(!k)
		return ;
	if(tr[k].v>x)
		ans=tr[k].v,query_sub(tr[k].l,x);
	else
		query_sub(tr[k].r,x);
}

int main()
{
	srand((unsigned int)time(NULL));
	in(n);
	while(n--)
	{
		in(opt);in(x);
		switch(opt)
		{
			case 1:insert(root,x);break;
			case 2:del(root,x);break;
			case 3:printf("%d
",query_rank(root,x));break;
			case 4:printf("%d
",query_num(root,x));break;
			case 5:query_pro(root,x);printf("%d
",ans);break;
			case 6:query_sub(root,x);printf("%d
",ans);break;
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/syhien/p/7994364.html