Cod sursa(job #1163906)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 1 aprilie 2014 18:27:05
Problema Zeap Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 6.8 kb
#include <fstream>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#define LG 20000000
using namespace std;
int ind;
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[LG];

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 = 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)) // 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[ind] < '0' || '9' < buffer[ind])
	{
		ind++;
		if(ind == LG)
		{
			fread(buffer, 1, LG, stdin);
			ind = 0;
		}
	}
	x = 0;
	while('0' <= buffer[ind] && buffer[ind] <= '9')
	{
		x = x * 10 + buffer[ind] - '0';
		ind++;
		if(ind == LG)
		{
			fread(buffer, 1, LG, stdin);
			ind = 0;
		}
	}
}

int main()
{
	int x;
	T = new Treap;
	nil = new Treap;
	srand(time(NULL));
	freopen("zeap.in", "r", stdin);
	fread(buffer, 1, LG, stdin);
	freopen("zeap.out", "w", stdout);
	while(ind < LG)
	{
		if(!Litera(buffer[ind]) && !Cifra(buffer[ind]))
			break;
		if(buffer[ind] == 'I') // insereaza
		{
			ind++;
			if(ind == LG)
			{
				fread(buffer, 1, LG, stdin);
				ind = 0;
			}
			Citeste(x);
			if(Search(T, x) == 0)
				Insert(T, x);
		}
		else
		{
			if(buffer[ind] == 'S') // sterge
			{
				ind++;
				if(ind == LG)
				{
					fread(buffer, 1, LG, stdin);
					ind = 0;
				}
				Citeste(x);
				if(Search(T, x) == 1)
					Erase(T, x);
				else
					printf("-1\n");
			}
			else
			{
				if(buffer[ind] == 'C') // cauta
				{
					ind++;
					if(ind == LG)
					{
						fread(buffer, 1, LG, stdin);
						ind = 0;
					}
					Citeste(x);
					printf("%d\n", Search(T, x));
				}
				else
				{
					ind++;
					if(ind == LG)
					{
						fread(buffer, 1, LG, stdin);
						ind = 0;
					}
					if(buffer[ind] == 'A') // max-dif
					{
						ind++;
						if(ind == LG)
						{
							if(fread(buffer, 1, LG, stdin))
								ind = 0;
						}
						ind++;
						if(ind == LG)
						{
							if(fread(buffer, 1, LG, stdin))
								ind = 0;
						}
						printf("%d\n", T -> maxdif);
					}
					else // min-dif
					{ 
						ind++;
						if(ind == LG)
						{
							if(fread(buffer, 1, LG, stdin))
								ind = 0;
						}
						ind++;
						if(ind == LG)
						{
							if(fread(buffer, 1, LG, stdin))
								ind = 0;
						}
						printf("%d\n", T -> mindif);
					}
				}
			}
		}
		ind++;
		if(ind == LG)
		{
			if(fread(buffer, 1, LG, stdin))
				ind = 0;
		}
	}
	return 0;
}