Cod sursa(job #463699)

Utilizator blasterzMircea Dima blasterz Data 17 iunie 2010 12:01:55
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.04 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 == 0) return ;
	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->p=rand();
		n->h=1;
		n->min=n->max=v;
		n->mindif=0x3f3f3f3f;
		return ;
	}
	
	if(v < n->v)
	{
		insert(n->l, v);
//		if(n->l->p > n->p) rotleft(n);
	}
	
	if(v > n->v)
	{
		insert(n->r, v);
		//if(n->r->p > n->p) rotright(n);
	}
	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;
}