Cod sursa(job #1984084)

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

#include <iostream>
#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);

	if (Root == NULL)
		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);

	if (tmp == NULL)
		cout << "-1\n";
	else
		delete tmp, nrNodes --;

	Merge(Root, left, right);
}

void PrintMax()
{
	if (nrNodes < 2)
		cout << -1 << '\n';
	else
		cout << Root->max - Root->min << '\n';
}

void PrintMin()
{
	if (nrNodes < 2)
		cout << -1 << '\n';
	else
		cout << Root->minDif << '\n';
}

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

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

	if (Root != NULL)
		cout << "1\n";
	else
		cout << "0\n";

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

int main()
{
	srand(time(NULL));

	freopen("zeap.in", "r", stdin);
	freopen("zeap.out", "w", stdout);

	char task[20]; 
	while (cin.getline(task, 20))
	{
		char *p = strtok(task, " ");

		switch (*p)
		{
		case 'I': Insert( stoi(strtok(NULL, " "))); break;
		case 'S': Delete( stoi(strtok(NULL, " "))); break;
		case 'C': Search( stoi(strtok(NULL, " "))); break;
		default:
			if (*(p + 1) == 'A') PrintMax();
			else PrintMin();
			break;
		}

	}

    return 0;
}