P3369 [Template] General Balance Tree (Treap/SBT)

Topic Description

You need to write a data structure (referable title) to maintain some numbers, which need to provide the following operations:

  1. Insert x number

  2. Delete the number x (if there are more than one identical number, because only one is deleted)

  3. Query the ranking of x numbers (if there are multiple identical numbers, because of the lowest output ranking)

  4. Number of queries ranked x

  5. The precursor of finding x (the precursor is defined as less than X and the largest number)

  6. Find the succession of x (succession is defined as the number greater than x and the smallest)

Input and output format

Input format:

The first action n represents the number of operations. The following N lines have two numbers opt and x for each row. Opti represents the ordinal number of operations (1<=opt<=6).

Output format:

For operations 3, 4, 5, 6, output a number per line to indicate the corresponding answer

Input and Output Samples

Input sample #1:
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Output sample #1:
106465
84185
492737

Explain

Space-time constraints: 1000ms,128M

1.n Data Range: n<=100000

2. Data range of each number: [-1e7,1e7]

Source: Tyvj1728, formerly known as Ordinary Balance Tree

Thank you here.



Balance tree bare question, but for the budding. Ah Ah Ah Ah Ah Ah Ah

I heard treap is a binary search tree, but sometimes it degenerates into a chain. In order to prevent this, a random value is dummied to make the tree satisfy the nature of the heap. If the tree is not satisfied, it needs to rotate.


#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int n,root,cnt,ans;
struct treap
{
	int l,r,val,w,sz,rnd;
}t[120005];
void update(int k)
{
	t[k].sz=t[t[k].l].sz+t[t[k].r].sz+t[k].w;
}
void lt(int &k)
{
	int now=t[k].r;
	t[k].r=t[now].l;
	t[now].l=k;
	t[now].sz=t[k].sz;
	update(k);
	k=now;
}
void rt(int &k)
{
	int now=t[k].l;
	t[k].l=t[now].r;
	t[now].r=k;
	t[now].sz=t[k].sz;
	update(k);
	k=now;
}
void insert(int &k,int x)
{
	if(k==0)
	{
		t[++cnt].val=x;
		t[cnt].sz=1;
		t[cnt].w=1;
		t[cnt].rnd=rand();
		k=cnt;
		return ;
	}
	t[k].sz++;
	if(t[k].val==x)
		t[k].w++;
	else if(x>t[k].val)
	{
		insert(t[k].r,x);
		if(t[t[k].r].rnd<t[k].rnd)
			lt(k);
	}
	else
	{
		insert(t[k].l,x);
		if(t[t[k].l].rnd<t[k].rnd)
			rt(k);
	}
}
void del(int &k,int x)
{
	if(k==0)
		return ;
	if(t[k].val==x)
	{
		if(t[k].w>1)
		{
			t[k].w--;
			t[k].sz--;
			return ;
		}
		if(t[k].l*t[k].r==0)
			k=t[k].l+t[k].r;
		else
		{
			if(t[t[k].l].rnd<t[t[k].r].rnd)
			{
				rt(k);
				del(k,x);
			}
			else
			{
				lt(k);
				del(k,x);
			}
		}
		return ;
	}
	t[k].sz--;
	if(x>t[k].val)
		del(t[k].r,x);
	if(x<t[k].val)
		del(t[k].l,x);
}
void ask_p(int k,int x,int mode)
{
	if(mode==1)
	{
		if(!k)
			return ;
		if(t[k].val<x)
		{
			ans=t[k].val;
			ask_p(t[k].r,x,1);
		}
		else
			ask_p(t[k].l,x,1);
	}
	else
	{
		if(!k)
			return ;
		if(t[k].val>x)
		{
			ans=t[k].val;
			ask_p(t[k].l,x,2);
		}
		else
			ask_p(t[k].r,x,2);
	}
}
int ask_rank(int k,int x)
{
	if(!k)
		return 0;
	if(t[k].val==x)
		return t[t[k].l].sz+1;
	if(t[k].val<x)
		return t[k].w+t[t[k].l].sz+ask_rank(t[k].r,x);
	return ask_rank(t[k].l,x);
}
int ask_num(int k,int x)
{
	if(!k)
		return 0;
	if(x<=t[t[k].l].sz)
		return ask_num(t[k].l,x);
	if(x>t[t[k].l].sz+t[k].w)
		return ask_num(t[k].r,x-t[t[k].l].sz-t[k].w);
	return t[k].val;
}
int main()
{
	scanf("%d",&n);
	while(n--)
	{
		int opt,x;
		scanf("%d%d",&opt,&x);
		switch(opt)
		{
			case 1:
				insert(root,x);
				break;
			case 2:
				del(root,x);
				break;
			case 3:
				printf("%d\n",ask_rank(root,x));
				break;
			case 4:
				printf("%d\n",ask_num(root,x));
				break;
			case 5:
				ask_p(root,x,1);
				printf("%d\n",ans);
				break;
			case 6:
				ask_p(root,x,2);
				printf("%d\n",ans);
				break;
		}
	}
	return 0;
}

Keywords: less

Added by Jurik on Fri, 12 Jul 2019 21:26:20 +0300