Cod sursa(job #382111)

Utilizator victor.ionescuIonescu Victor Cristian victor.ionescu Data 12 ianuarie 2010 21:23:38
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.13 kb
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define INF 1000000005
struct treap {
	int key,prio,mind;
	treap *left,*right,*lmost,*rmost;
} *T,*nil;
char S[200];

inline int min(int x,int y){ return x<y?x:y; }


void get_mind(treap *T){
	T->lmost=T->left->lmost; if (T->lmost==nil) T->lmost=T;
	T->rmost=T->right->rmost; if (T->rmost==nil) T->rmost=T;

	T->mind=min(T->left->mind,T->right->mind);
	
	if (T->left!=nil) T->mind=min(T->mind,T->key-T->left->rmost->key);

	if (T->right!=nil) T->mind=min(T->mind,T->right->lmost->key-T->key);
}

treap* rot_left(treap* T){
	treap *aux=T->right;
	T->right=aux->left;
	aux->left=T;

	get_mind(T);
	get_mind(aux);
	
	return aux;
}

treap* rot_right(treap* T){
	treap *aux=T->left;
	T->left=aux->right;
	aux->right=T;

	get_mind(T);
	get_mind(aux);

	return aux;
}

treap* insert(treap* T,int key){
	
	if (T==nil){
		treap* aux;
		aux=new treap;
		aux->key=key;
		aux->prio=rand();
		aux->lmost=aux;
		aux->rmost=aux;
		aux->mind=INF;
		aux->left=nil;
		aux->right=nil;
		T=aux;
		return T;
	}

	if (key<T->key) {
		T->left=insert(T->left,key);
		if (T->prio<T->left->prio) T=rot_right(T);
		get_mind(T);
	} else {
		T->right=insert(T->right,key);
		if (T->prio<T->right->prio) T=rot_left(T);
		get_mind(T);
	}

	return T;
}

treap* search(treap *T,int key){
	if (T==nil) return nil;
	if (T->key==key) return T;
	if (key<T->key) return search(T->left,key); else return search(T->right,key);
}

treap* erase(treap *T){
	if (T->left==nil && T->right==nil){
		delete T;
		return nil;
	}

	if (T->left==nil){
		T=rot_left(T);
		T->left=erase(T->left);
	} else if (T->right==nil){
		T=rot_right(T);
		T->right=erase(T->right);
	} else 	if (T->left->prio<T->right->prio){
		T=rot_left(T);
		T->left=erase(T->left);
	} else {
		T=rot_right(T);
		T->right=erase(T->right);
	}
	
	get_mind(T);

	return T;
}

treap* err(treap *T,int key){
	if (T->key==key){
		T=erase(T);
		return T;
	}
	if (key<T->key) T->left=err(T->left,key); else T->right=err(T->right,key);
	get_mind(T);
	return T;
}


int main(){

	srand(time(NULL));

	nil=new treap;
	nil->key=0;
	nil->prio=-2;
	nil->mind=INF;
	nil->lmost=nil;
	nil->rmost=nil;
	nil->left=NULL;
	nil->right=NULL;

	T=nil;

	freopen("zeap.in","rt",stdin);
	freopen("zeap.out","wt",stdout);

	while (!feof(stdin)){

		fgets(S+1,150,stdin);
		scanf("\n");

		if (S[2]=='A'){
			if (T->lmost==T->rmost)
				printf("%d\n",-1); else printf("%d\n",T->rmost->key-T->lmost->key);
		} else if (S[2]=='I'){
			if (T->mind<INF) printf("%d\n",T->mind); else printf("%d\n",-1);
		} else {
			int ind=3;
			int x=0;
			while (S[ind]>='0' && S[ind]<='9'){
				x*=10;
				x+=(S[ind]-'0');
				++ind;
			}

			if (S[1]=='C'){
				treap* sol=search(T,x);
				if (sol==nil) printf("%d\n",0); else printf("%d\n",1);
			} else if (S[1]=='I'){
				treap* find=search(T,x);
				if (find==nil) T=insert(T,x); 
			} else if (S[1]=='S'){
				treap* find=search(T,x);
				if (find==nil) printf("%d\n",-1); else T=err(T,x);
			}
		}
	}

	fclose(stdin);
	fclose(stdout);

	return 0;
}