Cod sursa(job #1163838)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 1 aprilie 2014 17:23:27
Problema Zeap Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.08 kb
#include <fstream>
#include <ctime>
#include <cstdlib>
using namespace std;
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;

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))
		return;
	if(NIL(nod -> st) && NIL(nod -> dr))
	{
		nod -> mindif = nod -> maxdif = -1;
		nod -> last_St = nod -> last_Dr = nil;
		return;
	}
	if(NIL(nod -> st))
	{
		if(!NIL(nod -> dr -> last_Dr))
		{
			nod -> last_Dr = nod -> dr -> last_Dr;
			nod -> maxdif = max(abs(nod -> val - nod -> dr -> last_Dr -> val), nod -> dr -> maxdif);
		}
		else
		{
			nod -> last_Dr = nod -> dr;
			nod -> maxdif = max(abs(nod -> val - nod -> dr -> val), nod -> dr -> maxdif);
		}
		nod -> last_St = nil;
		if(!NIL(nod -> dr -> last_St))
			nod -> mindif = abs(nod -> val - nod -> dr -> last_St -> val);
		else
			nod -> mindif = abs(nod -> val - nod -> dr -> val);
		if(nod -> dr -> mindif >= 0)
			nod -> mindif = min(nod -> mindif, nod -> dr -> mindif);
		return;
	}
	if(NIL(nod -> dr))
	{
		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;
	}
	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 = rand() % 1000000000 + 1;
		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))
		{
			delete nod;
			nod = nil;
		}
		else
		{
			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);
}

int main()
{
	int x;
	char op[5];
	T = new Treap;
	nil = new Treap;
	srand(time(NULL));
	ifstream fin("zeap.in");
	ofstream fout("zeap.out");
	while(fin >> op)
	{
		if(op[0] == 'I') // insereaza
		{
			fin >> x;
			if(Search(T, x) == 0)
				Insert(T, x);
			continue;
		}
		if(op[0] == 'S') // sterge
		{
			fin >> x;
			if(Search(T, x) == 1)
				Erase(T, x);
			else
				fout << "-1\n";
			continue;
		}
		if(op[0] == 'C') // cauta
		{
			fin >> x;
			fout << Search(T, x) << "\n";
			continue;
		}
		if(op[1] == 'A') // max-dif
		{
			fout << (T -> maxdif) << "\n";
			continue;
		}
		if(op[1] == 'I') // min-dif
		{
			fout << (T -> mindif) << "\n";
			continue;
		}
	}
	fin.close();
	fout.close();
	return 0;
}