Cod sursa(job #1984090)

Utilizator horiainfoTurcuman Horia horiainfo Data 23 mai 2017 17:51:39
Problema Zeap Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
// Probleme.cpp : Defines the entry point for the console application.
//

#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <cstring>
#include <time.h>

#define INF 2000000000
using namespace std;

struct Treap {
	int key, priority;
	int max, min, minDif;
	Treap *left, *right;

	Treap(int key) : key(key) 
	{
		priority = rand() % INF;
		max = min = key, minDif = INF;
		left = right = NULL;
	}
} *Root;

int nrNodes;

void Update(Treap *root)
{
	root->max = root->min = root->key;
	root->minDif = INF;

	if (root->left != NULL)
	{
		root->max = max(root->max, root->left->max);
		root->min = min(root->min, root->left->min);
		root->minDif = min(root->left->minDif, root->key - root->left->max);
	}

	if (root->right != NULL)
	{
		root->max = max(root->max, root->right->max);
		root->min = min(root->min, root->right->min);
		root->minDif = min(root->minDif, min(root->right->minDif, root->right->min - root->key));
	}
}

void Split(Treap *root, int key, Treap *&left, Treap *&right)
{
	if (root == NULL)
	{
		left = NULL, right = NULL;
		return;
	}

	if (key < root->key)
		Split(root->left, key, left, root->left),
		right = root;
	else
		Split(root->right, key, root->right, right),
		left = root;

	Update(root);
}

void Merge(Treap *&root, Treap *left, Treap *right)
{
	if (left == NULL || right == NULL)
	{
		root = left != NULL ? left : right;
		return;
	}

	if (left->priority < right->priority)
		Merge(right->left, left, right->left),
		root = right;
	else
		Merge(left->right, left->right, right),
		root = left;

	Update(root);
}

void Insert(int key)
{
	Treap *left, *right;

	Split(Root, key, Root, right);
	Split(Root, key - 1, left, Root);

	Root = new Treap(key), nrNodes ++;

	Merge(Root, left, Root);
	Merge(Root, Root, right);
}

void Delete(int key)
{
	Treap *left, *right, *tmp;

	Split(Root, key, Root, right);
	Split(Root, key - 1, left, tmp);

	delete tmp, nrNodes --;
	Merge(Root, left, right);
}

int PrintMax()
{
	if (nrNodes < 2) return -1;
	else return Root->max - Root->min;
}

int PrintMin()
{
	if (nrNodes < 2) return -1;
	else return Root->minDif;
}

bool Find(Treap *node, int key)
{
	if (node == NULL) return false;
	if (node->key == key)	return true;

	if (key < node->key) return Find(node->left, key);
	if (key > node->key) return Find(node->right, key);
}

int main()
{
	srand(time(NULL));
	ifstream cin("zeap.in");
	ofstream fout("zeap.out");
	ios::sync_with_stdio(false);

	string s;
	while (cin >> s)
	{
		if (s == "MAX") cout << PrintMax() << '\n';
		else if (s == "MIN") cout << PrintMin() << '\n';
		else
		{
			int x; cin >> x;
			if (s == "I")
				if (!Find(Root, x)) Insert(x);

			if (s == "S")
				if (!Find(Root, x)) cout << "-1\n";
				else Delete(x);

			if (s == "C")
				cout << Find(Root, x) << '\n';
		}
	}
    return 0;
}