Cod sursa(job #1223743)

Utilizator ion824Ion Ureche ion824 Data 28 august 2014 18:47:44
Problema Zeap Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.2 kb
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int NM = 1050000;
const int NUM = 300000;
const int INF = 0x3f3f3f3f;
int mx[NM], mn[NM], Dm[NM], Dx[NM];
int st[NUM+5], K, Val1, Val2, poz, PPZ;
char s[20];

struct Node{
	int value,h,index;
	Node *left, *right;
};

struct AVL{
	Node *R, *NIL;
	
	AVL()
	{
		R = NIL = new Node;
		NIL->h = 0;
		NIL->left = NIL->right = NULL;
	}
	
	bool Search(int val)
	{
		return Search(R, val);
	}

	void Insert(int val, int poz)
	{
		R = Insert(R, val, poz);
	}

	void Delete(int val)
	{
		R = Delete(R, val);
	}

	bool Search(Node *N, int val)
	{
		if (N == NIL) return false;

		if (N->value == val) return true;

		if (val < N->value)
			return Search(N->left, val);
		else
			return Search(N->right, val);
	}

	Node* Insert(Node *N, int val, int poz)
	{
		if (N == NIL)
		{
			N = new Node;
			N->value = val;
			N->index = poz;
			N->left = N->right = NIL;
			N->h = 1;

			return N;
		}

		if (val <= N->value) N->left = Insert(N->left, val, poz);
		else N->right = Insert(N->right, val, poz);

		return Balance(N);
	}

	Node* Delete(Node *N, int val)
	{
		Node *t;
		if (N == NIL) return N;
		if (N->value == val)
		{
			if(!PPZ) PPZ = N->index;
			if (N->left == NIL || N->right == NIL)
			{
				if (N->left == NIL) t = N->right;
				else t = N->left;
				
				delete N;
				return t;
			}
			else
			{
				for (t = N->right; t->left != NIL; t = t->left);
				N->value = t->value;
				N->right = Delete(N->right, t->value);
				return Balance(N);
			}
		}

		if (val < N->value) N->left = Delete(N->left, val);
		else N->right = Delete(N->right, val);

		return Balance(N);
	}

	int Max(int a, int b)
	{
		return a>b ? a : b;
	}

	void GetHeight(Node *N)
	{
		N->h = 1 + Max(N->left->h, N->right->h);
	}

	Node* RotateLeft(Node *N)
	{
		Node *t = N->left;
		N->left = t->right;
		t->right = N;
		GetHeight(N);
		GetHeight(t);

		return t;
	}

	Node* RotateRight(Node *N)
	{
		Node *t = N->right;
		N->right = t->left;
		t->left = N;
		GetHeight(N);
		GetHeight(t);

		return t;
	}
	
	Node* Balance(Node *N)
	{
		GetHeight(N);

		if (N->left->h > N->right->h + 1)
		{
			if (N->left->right->h > N->left->left->h)
				N->left = RotateRight(N->left);
			N = RotateLeft(N);
		}
		else
		if (N->right->h > N->left->h + 1)
		{
			if (N->right->left->h > N->right->right->h)
				N->right = RotateLeft(N->right);
			N = RotateRight(N);
		}

		return N;
	}
} Root;

int abs2(int x) { return (x<0) ? -x : x; }

void build(int nod, int l, int r){
	if(l == r)
	{
		mn[nod] = Dm[nod] = INF;
		mx[nod] = Dx[nod] = -INF;
		return ;
	}
	int div = (l+r) / 2;
	
	build(2*nod,l,div);
	build(2*nod+1,div+1,r);
	
	Dm[nod] = min(Dm[2*nod], Dm[2*nod+1]);
	if(mx[2*nod] != -INF && mx[2*nod+1] != -INF) Dm[nod] = min(Dm[nod], abs2(mx[2*nod] - mx[2*nod+1]));
	if(mn[2*nod] !=  INF && mn[2*nod+1] !=  INF) Dm[nod] = min(Dm[nod], abs2(mn[2*nod] - mn[2*nod+1])); 
	
	Dx[nod] = max(Dx[2*nod], Dx[2*nod+1]);
	if(mx[2*nod] != -INF && mn[2*nod+1] != INF) Dx[nod] = max(Dx[nod], abs2(mx[2*nod] - mn[2*nod+1]));
	if(mn[2*nod] != INF && mx[2*nod+1] != -INF) Dx[nod] = max(Dx[nod], abs2(mn[2*nod] - mx[2*nod+1]));
	
	mx[nod] = max(mx[2*nod], mx[2*nod+1]);
	mn[nod] = min(mn[2*nod], mn[2*nod+1]);
}

void update(int nod, int l, int r){
	
	if(l == r)
	{
		mn[nod] = Val1;
		mx[nod] = Val2;
		return ;
	}
	
	int div = (l+r) / 2;
	
	if(poz <= div) update(2*nod, l, div);
	else update(2*nod+1, div+1, r);
	
	Dm[nod] = min(Dm[2*nod], Dm[2*nod+1]);
	if(mx[2*nod] != -INF && mx[2*nod+1] != -INF) Dm[nod] = min(Dm[nod], abs2(mx[2*nod] - mx[2*nod+1]));
	if(mn[2*nod] !=  INF && mn[2*nod+1] !=  INF) Dm[nod] = min(Dm[nod], abs2(mn[2*nod] - mn[2*nod+1])); 
	
	Dx[nod] = max(Dx[2*nod], Dx[2*nod+1]);
	if(mx[2*nod] != -INF && mn[2*nod+1] != INF) Dx[nod] = max(Dx[nod], abs2(mx[2*nod] - mn[2*nod+1]));
	if(mn[2*nod] != INF && mx[2*nod+1] != -INF) Dx[nod] = max(Dx[nod], abs2(mn[2*nod] - mx[2*nod+1]));
	
	mx[nod] = max(mx[2*nod], mx[2*nod+1]);
	mn[nod] = min(mn[2*nod], mn[2*nod+1]);	
}

int main(){
	freopen("zeap.in","r",stdin);
	freopen("zeap.out","w",stdout);	
	int i,j,l,x,nr=0;
	
	build(1,1,NUM);
	
	for(i=NUM;i>0;--i) st[NUM-i+1] = i;
	K = NUM;
	
	while(gets(s))
	{
		l = strlen(s);
		if(s[0] == 'I' || s[0] == 'S' || s[0] == 'C')
		{
			i = 2;
			x = 0;
			while(i<l && s[i] >='0' && s[i]<='9') x=(x*10)+(s[i++]-'0');
		}
		if(s[0] == 'I')
		{
			if(!Root.Search(x))
			{
				Root.Insert(x, st[K]);
				Val1 = Val2 = x;
				poz = st[K];
				update(1,1,NUM);
				-- K;
				nr ++;	
			}
		}
		if(s[0] == 'S')
		{
			if(Root.Search(x))
			{
				PPZ = 0;
				Root.Delete(x);
				st[++K] = PPZ;
				Val1 = INF;
				Val2 = - INF;
				poz = PPZ;
				update(1,1,NUM);
				nr --;
			}
			else
			printf("-1\n");
		}
		if(s[0] == 'C')
		{
			if(Root.Search(x)) printf("1\n");
			else printf("0\n");
		}
		if(s[1] == 'A')
		{
			if(nr > 1)
			{
				printf("%d\n",Dx[1]);
			}
			else printf("-1\n");
		}
		if(s[1] == 'I')
		{
			if(nr > 1)
			{
				printf("%d\n",Dm[1]);
			}
			else printf("-1\n");
		}
	}	
	
	return 0;
}