Cod sursa(job #1539969)

Utilizator TeodorCotetCotet Teodor TeodorCotet Data 1 decembrie 2015 21:08:43
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.13 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("hashuri.in");
ofstream fout("hashuri.out");

class Nod {

public:
	
	Nod* st; Nod* dr;

	int h; //adancimea maxima a celor doi subarbori
	int key;

	Nod() {

		this->st = NULL;
		this->dr = NULL;
		this->h = 0;
		this->key = 0;
	}

	Nod(Nod* st, Nod* dr, int h, int key) {

		this->st = st;
		this->dr = dr;
		this->h = h;
		this->key = key;
	}
};


Nod* nil;

int getH(Nod* nod) {

	return 1 + max(nod->st->h, nod->dr->h);
}


Nod* rotateRight(Nod* curent) {

	Nod* leftSon = curent->st;
	curent->st = leftSon->dr;
	leftSon->dr = curent;

	curent->h = getH(curent);
	leftSon->h = getH(leftSon);

	return leftSon;
}

Nod* rotateLeft(Nod* curent) {

	Nod* rightSon = curent->dr;
	curent->dr = rightSon->st;
	rightSon->st = curent;

	curent->h = getH(curent);
	rightSon->h = getH(rightSon);

	return rightSon;
}



Nod* balance(Nod* curent) {

	curent->h = getH(curent);

	if(curent->st->h > curent->dr->h + 1) {

		//LR
		if(curent->st->dr->h > curent->st->st->h)
			curent->st = rotateLeft(curent->st);
		//LL
		curent = rotateRight(curent);

	}  else  if(curent->dr->h > curent->st->h + 1) {

			//RL

			if(curent->dr->st->h > curent->dr->dr->h)
				curent->dr = rotateRight(curent->dr);

			//RR
			curent = rotateLeft(curent);
	}

	return curent;
}

Nod* insert(Nod* curent,const int &key) {

	if(curent == nil) {

		curent = new Nod(nil, nil, 1, key);
		return curent;
	} 

	if(curent->key > key)
		curent->st = insert(curent->st, key);
	else 
		curent->dr = insert(curent->dr, key);

	return balance(curent);
}


Nod* erase(Nod* curent,const int &key) {

	if(curent == nil) 
		return curent;

	if(curent->key == key) {

		if(curent->st == nil || curent->dr == nil) {

			Nod* ret = (curent->st == nil) ? curent->dr : curent->st;
			delete curent;

			return ret;
		} else {

			//cautam nodul cu care o sa inlocuim
			Nod* p;
			for(p = curent->st; p->dr != nil ; p = p->dr) ;

			curent->key = p->key;

			curent->st = erase(curent->st, p->key);

			return balance(curent);
		}
	}

	if(curent->key < key)
		curent->dr = erase(curent->dr, key);


	if(curent->key > key)
		curent->st = erase(curent->st, key);

	return balance(curent);

}


int search(Nod* curent, const int& key) {

	if(curent == nil)
		return 0;
	
	if(curent->key < key)
		return search(curent->dr, key);
	
	if(curent->key > key)
		return search(curent->st, key);

	if(curent->key == key)
		return 1;

}


void inOrdine(Nod* curent) {

	if(curent->st != nil)
		inOrdine(curent->st);
	
	fout << curent->key << " "; 
	
	if(curent->dr != nil)
		inOrdine(curent->dr);

}

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


void checkHeight(Nod* root) {

	if(root == nil) {
		root->h = 0;
		return ;
	}

	
	checkHeight(root->st);
	checkHeight(root->dr);

	root->h = max(root->st->h, root->dr->h) + 1;

	if( modul(root->st->h - root->dr->h) > 1 )
		cout << "nasol" << '\n'; 
}

int main() {


	nil = new Nod();
	Nod* root = nil;

	int type; int x; int N;

	fin >> N;

	while(N--) {


		fin >> type >> x;

		switch(type) {	

			case 1: root = insert(root, x); break;
			case 2: root = erase(root, x); break;
			case 3: fout << search(root, x) << '\n'; break;
		}
	}


	return 0;

}