Cod sursa(job #1163928)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 1 aprilie 2014 18:39:13
Problema Zeap Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 6.02 kb
#include <fstream>
#include <ctime>
#include <algorithm>
#include <cstdio>
#include <numeric>
using namespace std;
int ind, chei[300100], nrchei = 1;
struct Treap
{
	Treap *st, *dr, *last_St, *last_Dr;
	int val, cheie, mindif, maxdif;
	Treap()
	{
		st = dr = last_St = last_Dr = NULL;
		val = cheie = 0;
		mindif = maxdif = -1;
	}
};
Treap *T, *nil;
char *buffer;

inline bool NIL(Treap *nod)
{
	if(nod == nil)
		return true;
	if(nod == NULL)
		return true;
	if(nod -> cheie == 0)
		return true;
	return false;
}

inline void Update(Treap * &nod)
{
	if(NIL(nod)) // e nil
		return;
	if(NIL(nod -> st) && NIL(nod -> dr)) // e frunza
	{
		nod -> mindif = nod -> maxdif = -1;
		nod -> last_St = nod -> last_Dr = nil;
		return;
	}
	if(NIL(nod -> st)) // are doar fiu drept
	{
		if(!NIL(nod -> dr -> last_Dr))
		{
			nod -> last_Dr = nod -> dr -> last_Dr;
			nod -> maxdif = max(nod -> dr -> last_Dr -> val - nod -> val , nod -> dr -> maxdif);
		}
		else
		{
			nod -> last_Dr = nod -> dr;
			nod -> maxdif = max(nod -> dr -> val - nod -> val, nod -> dr -> maxdif);
		}
		nod -> last_St = nil;
		if(!NIL(nod -> dr -> last_St))
			nod -> mindif = nod -> dr -> last_St -> val - nod -> val;
		else
			nod -> mindif = nod -> dr -> val - nod -> val;
		if(nod -> dr -> mindif >= 0)
			nod -> mindif = min(nod -> mindif, nod -> dr -> mindif);
		return;
	}
	if(NIL(nod -> dr)) // are doar fiu stang
	{
		if(!NIL(nod -> st -> last_St))
		{
			nod -> last_St = nod -> st -> last_St;
			nod -> maxdif = max(abs(nod -> val - nod -> st -> last_St -> val), nod -> st -> maxdif);
		}
		else
		{
			nod -> last_St = nod -> st;
			nod -> maxdif = max(abs(nod -> val - nod -> st -> val), nod -> st -> maxdif);
		}
		nod -> last_Dr = nil;
		if(!NIL(nod -> st -> last_Dr))
			nod -> mindif = abs(nod -> val - nod -> st -> last_Dr -> val);
		else
			nod -> mindif = abs(nod -> val - nod -> st -> val);
		if(nod -> st -> mindif >= 0)
			nod -> mindif = min(nod -> mindif, nod -> st -> mindif);
		return;
	}
	// are ambii fii
	int a, b;
	if(!NIL(nod -> st -> last_St))
	{
		nod -> last_St = nod -> st -> last_St;
		a = nod -> st -> last_St -> val;
	}
	else
	{
		nod -> last_St = nod -> st;
		a = nod -> st -> val;
	}
	if(!NIL(nod -> dr -> last_Dr))
	{
		nod -> last_Dr = nod -> dr -> last_Dr;
		b = nod -> dr -> last_Dr -> val;
	}
	else
	{
		nod -> last_Dr = nod -> dr;
		b = nod -> dr -> val;
	}
	nod -> maxdif = max(abs(a - b), max(nod -> st -> maxdif, nod -> dr -> maxdif));
	if(!NIL(nod -> st -> last_Dr))
		a = nod -> st -> last_Dr -> val;
	else
		a = nod -> st -> val;
	if(!NIL(nod -> dr -> last_St))
		b = nod -> dr -> last_St -> val;
	else
		b = nod -> dr -> val;
	nod -> mindif = min(abs(a - nod -> val), abs(b - nod -> val));
	if(nod -> st -> mindif >= 0)
		nod -> mindif = min(nod -> mindif, nod -> st -> mindif);
	if(nod -> dr -> mindif >= 0)
		nod -> mindif = min(nod -> mindif, nod -> dr -> mindif);
}

inline int Search(Treap *nod, int x)
{
	if(NIL(nod))
		return 0;
	if(nod -> val == x)
		return 1;
	if(nod -> val > x)
		return Search(nod -> st, x);
	return Search(nod -> dr, x);
}

inline void RotateLeft(Treap * &nod)
{
	Treap *aux = nod -> st;
	nod -> st = aux -> dr;
	aux -> dr = nod;
	nod = aux;
}

inline void RotateRight(Treap * &nod)
{
	Treap *aux = nod -> dr;
	nod -> dr = aux -> st;
	aux -> st = nod;
	nod = aux;
}

inline void Balance(Treap * &nod)
{
	if(nod -> st -> cheie > nod -> cheie)
		RotateLeft(nod);
	else
		if(nod -> dr -> cheie > nod -> cheie)
			RotateRight(nod);
	Update(nod -> st);
	Update(nod -> dr);
	Update(nod);
}

inline void Insert(Treap * &nod, int x)
{
	if(NIL(nod))
	{
		nod = new Treap;
		nod -> val = x;
		nod -> cheie = chei[nrchei++];
		nod -> mindif = nod -> maxdif = -1;
		nod -> st = nod -> dr = nod -> last_St = nod -> last_Dr = nil;
		return;
	}
	if(nod -> val > x)
		Insert(nod -> st, x);
	else
		Insert(nod -> dr, x);
	Balance(nod);
}

inline void Erase(Treap * &nod, int x)
{
	if(NIL(nod))
		return;
	if(nod -> val > x)
		Erase(nod -> st, x);
	if(nod -> val < x)
		Erase(nod -> dr, x);
	if(nod -> val == x)
	{
		if(NIL(nod -> st) && NIL(nod -> dr)) // e frunza
		{
			delete nod;
			nod = nil;
		}
		else // altfel tot rotesc ca sa-l fac frunza
		{
			if(nod -> st -> cheie > nod -> dr -> cheie)
				RotateLeft(nod);
			else
				RotateRight(nod);
			Update(nod -> st);
			Update(nod -> dr);
			Update(nod);
			Erase(nod, x);
		}
	}
	Update(nod -> st);
	Update(nod -> dr);
	Update(nod);
}

inline bool Litera(char c)
{
	if('A' <= c && c <= 'Z')
		return true;
	return false;
}

inline bool Cifra(char c)
{
	if('0' <= c && c <= '9')
		return true;
	return false;
}

inline void Citeste(int &x)
{
	while(*buffer < '0' || '9' < *buffer)
		buffer++;
	x = 0;
	while('0' <= *buffer && *buffer <= '9')
	{
		x = x * 10 + *buffer - '0';
		buffer++;
	}
}

int main()
{
	int x;
	T = new Treap;
	nil = new Treap;
	srand(time(NULL));
	iota(chei + 1, chei + 300001, 1);
	random_shuffle(chei + 1, chei + 300001);
	
	ifstream fin("zeap.in");
	fin.seekg(0, ios::end);
	int fs = fin.tellg();
	fin.seekg(0, ios::beg);
	buffer = (char *)malloc(fs);
	fin.getline(buffer, fs, 0);
	freopen("zeap.out", "w", stdout);
	
	while(Litera(*buffer) || Cifra(*buffer))
	{
		if(*buffer == 'I') // insereaza
		{
			buffer++;
			Citeste(x);
			if(Search(T, x) == 0)
				Insert(T, x);
		}
		else
		{
			if(*buffer == 'S') // sterge
			{
				buffer++;
				Citeste(x);
				if(Search(T, x) == 1)
					Erase(T, x);
				else
					printf("-1\n");
			}
			else
			{
				if(*buffer == 'C') // cauta
				{
					buffer++;
					Citeste(x);
					printf("%d\n", Search(T, x));
				}
				else
				{
					buffer++;
					if(*buffer == 'A') // max-dif
					{
						buffer++;
						buffer++;
						printf("%d\n", T -> maxdif);
					}
					else // min-dif
					{ 
						buffer++;
						buffer++;
						printf("%d\n", T -> mindif);
					}
				}
			}
		}
		buffer++;
	}
	return 0;
}