Cod sursa(job #463733)

Utilizator blasterzMircea Dima blasterz Data 17 iunie 2010 12:49:41
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.24 kb
//avl.cpp
//folosind treapuri:P
using namespace std;
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <algorithm>
#include <string>

struct nod { int v, max, min, mindif, h; nod *l, *r;};

typedef nod * tree;

tree R, nil;

inline void init ()
{
	nil = new nod;
	nil->l = nil->r = 0;
	nil->v = nil->max = -0x3f3f3f3f;
	nil->min = nil->mindif = 0x3f3f3f3f;
	nil->h = 0;
	R = nil;
}

inline void geth (tree &n)
{
	if (n == nil) return;
	n->h = max (n->l->h, n->r->h) + 1;
}

inline void update (tree &n)
{
	if (n == nil) 
		return;
	n->mindif = 0x3f3f3f3f;
	n->max = n->min = n->v;
	n->h = max (n->l->h, n->r->h) + 1;
	
	n->min = min (n->min, n->l->min);
	n->max = max (n->max, n->l->max);
	n->mindif = min (n->mindif, n->v - n->l->max);
	n->mindif = min (n->mindif, n->l->mindif);

	n->min = min (n->min, n->r->min);
	n->max = max (n->max, n->r->max);
	n->mindif = min (n->mindif, n->r->min - n->v);
	n->mindif = min (n->mindif, n->r->mindif);
}

inline void rotleft (tree &n)
{
	tree t = n->l;
	n->l = t->r;
	t->r = n;
	update (n);update (t);
	n = t;
}

inline void rotright (tree &n)
{
	tree t = n->r;
	n->r = t->l;
	t->l = n;
	update (n);update (t);
	n = t;
}

inline void balance (tree &n)
{
	if (n == nil) return;
	update (n);
	if (n->l->h > n->r->h + 1)
	{
		if (n->l->r->h > n->l->l->h) 
			rotright (n->l);
		rotleft (n);
	}
	else
	if (n->r->h > n->l->h + 1)
	{
		if (n->r->l->h > n->r->r->h) 
			rotleft (n->r);
		rotright(n);
	}
	update(n);
}

inline bool find (tree &n, int v)
{
	if (n == nil) return 0;
	if (v < n->v) return find (n->l,v);
	if (v > n->v) return find (n->r, v);
	if (v == n->v) return 1;
}

inline void insert (tree &n, int v)
{
	if (n == nil)
	{
		n = new nod;
		n->l = n->r = nil;
		n->v = v;
		n->h = 1;
		n->min = n->max = v;
		n->mindif = 0x3f3f3f3f;
		return ;
	}
	
	if (v < n->v)
		insert (n->l, v);
	
	if (v > n->v)
		insert (n->r, v);

	balance (n);
	update (n);
}

inline void strg (tree &n, int v)
{
	if (n == nil) 
		return ;
	
	if (v < n->v) strg(n->l, v);
	if (v > n->v) strg(n->r, v);
	if (v == n->v)
	{
		if (n->l == nil && n->r == nil) 
		{
			delete n;
			n=nil;
			return;
		}
		
		if (n->l->h > n->r->h) 
			rotleft (n);
		else 
			rotright (n);
		
		strg (n,v);
	}
	balance (n);
}

inline void sterge (tree &n, int v)
{
	if (!find (n, v))
	       	printf ("-1\n");
	else 
		strg (n, v);
}

inline int max_dif (tree n)
{
	if (n == nil) 
		return -1;
	if (n->l == nil && n->r == nil)
	       	return -1;
	return n->max - n->min;
}

inline int min_dif (tree n)
{
	if (n == nil)
	       	return -1;
	if (n->l == nil && n->r == nil) 
		return -1;
	return n->mindif;
}

int main ()
{
	srand (time (0));
	init ();
	
	freopen ("zeap.in","r",stdin);
	freopen( "zeap.out","w",stdout);
	
	while (!feof (stdin))
	{
		char ax[16];
		memset (ax, 0, sizeof(ax));
		gets (ax);
		if (ax[0] == 'M')
		{
			if (ax[1] == 'A') 
				printf ("%d\n", max_dif (R));
			else 
				printf ("%d\n", min_dif (R));
		}
		else 
		{
			int pz = 1;
			while (ax[pz] < '0' || ax[pz] > '9')
			       	++pz;
			int x = 0;
			while (ax[pz] >= '0' && ax[pz] <= '9')
			       	x = x * 10 + ax[pz] - '0', ++pz;

			
			if (ax[0] == 'I')
			       	insert (R, x);
			if (ax[0] == 'S')
			       	sterge (R, x);
			if (ax[0] == 'C')
			       	printf ("%d\n", find (R, x));
		}
	}
	return 0;
}