Cod sursa(job #452335)

Utilizator jeanFMI - Petcu Ion Cristian jean Data 10 mai 2010 12:55:04
Problema Zeap Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.38 kb
#include<stdio.h>
#include<stdlib.h>
#define Inf 1<<30
#define Nmax 100000
#define Black 0
#define Red 1

int i,nr,ok,N,sol;
char op[4];

struct RBT {int color, key;
			RBT *left, *right, *parent;} *Root,*NIL;

	
RBT* find(int k)
{
	RBT *c=Root;
	
	while(c->key!=k && c!=NIL)
		if(c->key<k) c=c->right;
			else c=c->left;
	return c;
}			
	
RBT* BST_Minim(RBT *x)
{
	while(x->left!=NIL)
		x=x->left;
	return x;
}

RBT* BST_Maxim(RBT *x)
{
	while(x->right!=NIL)
		x=x->right;
	return x;
}

RBT* BST_Insereaza(int k)
{
	if(Root==NIL)
	{
		Root= new RBT;
		Root->key=k;
		Root->parent=Root->left=Root->right=NIL;
		return Root;
	}
	RBT *z;
	z = new RBT;
	z->key=k;
	z->parent=z->left=z->right=NIL;
	
	RBT *y=NIL;
	RBT *x=Root;
	
	while(x!=NIL)
	{
		y=x;
		if(z->key==x->key) return NIL;
		if(z->key < x->key)
			x=x->left;
		else 
			x=x->right;
	}
	z->parent=y;
	if(y==NIL)
		Root=z;
	else if(z->key < y->key)
		y->left=z;
	else 
		y->right=z;
	
	return z;
}

void Roteste_Stanga(RBT *x)
{
	RBT *y=x->right;
	x->right=y->left;
	
	if(y->left != NIL)
		y->left->parent=x;
	y->parent=x->parent;
	
	if(x->parent==NIL)
		Root=y;
	else 
		if(x==x->parent->left)
			x->parent->left=y;
		else
			x->parent->right=y;
	
	y->left=x;
	x->parent=y;
}

void Roteste_Dreapta(RBT *x)
{
	RBT *y=x->left;
	x->left=y->right;
	
	if(y->right!=NIL)
		y->right->parent=x;
	y->parent=x->parent;
	
	if(x->parent==NIL)
		Root=y;
	else 
		if(x==x->parent->left)
			x->parent->left=y;
		else
			x->parent->right=y;
	
	y->right=x;
	x->parent=y;
}

void RBT_Insereaza(int k)
{
	RBT *x=BST_Insereaza(k);
	if(x==NIL) return ;
	N++;
	x->color=Red;
	
	while(x!=Root && x->parent->color==Red)
		if(x->parent==x->parent->parent->left)
		{
			RBT *y=x->parent->parent->right;
			if(y->color==Red)
			{
				x->parent->color=Black;
				y->color=Black;
				x->parent->parent->color=Red;
				x=x->parent->parent;
			}
			else
			{
				if(x==x->parent->right)
				{
					x=x->parent;
					Roteste_Stanga(x);
				}
				x->parent->color=Black;
				x->parent->parent->color=Red;
				Roteste_Dreapta(x->parent->parent);
			}
		}
		else
		{
			RBT *y=x->parent->parent->left;
			if(y->color==Red)
			{
				x->parent->color=Black;
				y->color=Black;
				x->parent->parent->color=Red;
				x=x->parent->parent;
			}
			else
			{
				if(x==x->parent->left)
				{
					x=x->parent;
					Roteste_Dreapta(x);
				}
				x->parent->color=Black;
				x->parent->parent->color=Red;
				Roteste_Stanga(x->parent->parent);
			}
		}
	Root->color=Black;
}	

void RBT_Sterge_Repara(RBT *x)
{
	while(x!=Root && x->color==Black)
		if(x==x->parent->left)
		{
			RBT *w=x->parent->right;
			if(w->color==Red)
			{
				w->color=Black;
				x->parent->color=Red;
				Roteste_Stanga(x->parent);
				w=x->parent->right;
			}
			
			if(w->left->color==Black && w->right->color==Black)
			{
				w->color=Red;
				x=x->parent;
			}
			else
			{
				if(w->right->color==Black)
				{
					w->left->color=Black;
					w->color=Red;
					Roteste_Dreapta(w);
					w=x->parent->right;
				}
				w->color=x->parent->color;
				x->parent->color=Black;
				w->right->color=Black;
				Roteste_Stanga(x->parent);
				x=Root;
			}
		}
		else
		{
			RBT *w=x->parent->left;
			if(w->color==Red)
			{
				w->color=Black;
				x->parent->color=Red;
				Roteste_Dreapta(x->parent);
				w=x->parent->left;
			}
			
			if(w->left->color==Black && w->right->color==Black)
			{
				w->color=Red;
				x=x->parent;
			}
			else
			{
				if(w->left->color==Black)
				{
					w->right->color=Black;
					w->color=Red;
					Roteste_Stanga(w);
					w=x->parent->left;
				}
				w->color=x->parent->color;
				x->parent->color=Black;
				w->left->color=Black;
				Roteste_Dreapta(x->parent);
				x=Root;
			}
		}
	x->color=Black;
}

void RBT_Sterge(int k)
{
	RBT *z=find(k);
	RBT *x,*y;
	
	if(z==NIL) {ok=0; return;}
	N--;
	if(z->left==NIL || z->right==NIL)
		y=z;
	else y=BST_Maxim(z->right);
	
	if(y->left!=NIL)
		x=y->left;
	else 
		x=y->right;
	
	x->parent=y->parent;
	
	if(y->parent==NIL)
		Root=x;
	else
		if(y==y->parent->left)
			y->parent->left=x;
		else
			y->parent->right=x;
	
	if(y!=z)
		z->key=y->key;
		
	if(y->color==Black)
		RBT_Sterge_Repara(x);
	
	delete y;
	y=NIL;
}

void Dif_Min(RBT *nod)
{
	if(nod==NIL) return ;
	
	if(nod != Root)
		if(sol > abs(nod->key-nod->parent->key) )
			sol=abs(nod->key-nod->parent->key);
	Dif_Min(nod->left);	
	Dif_Min(nod->right);
}
int main()
{
	freopen("zeap.in","r",stdin);
	freopen("zeap.out","w",stdout);
	
	NIL =  new RBT;
	NIL->key=NIL->color=0;
	NIL->parent=NIL->left=NIL->right=NULL;
	
	//Root = new RBT;
	Root = NIL;
	
	

	while( !feof(stdin) )
	{
		scanf("%s",op);
		
		if(op[0]=='I')
		{
			scanf("%d",&nr);
			RBT_Insereaza(nr);
		}
		else if(op[0]=='S')
		{
			scanf("%d",&nr);
			ok=1;
			RBT_Sterge(nr);
			if(!ok) printf("-1\n");
		}
		else if(op[0]=='C')
		{
			scanf("%d",&nr);
			if(find(nr)==NIL) printf("0\n");
			else printf("1\n");
		}
		else if(op[1]=='I')
		{
			if(N<2) printf("-1\n");
			else
			{
				sol=Inf;
				Dif_Min(Root);
				printf("%d\n",sol);		
			}
		}
		else
		{
			if(N<2) printf("-1\n");
			else
			printf("%d\n",BST_Maxim(Root)->key-BST_Minim(Root)->key);
		}
	}
	
	return 0;
}