Cod sursa(job #1855726)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 23 ianuarie 2017 21:24:56
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

struct nod{
	int val, big, small, diff, prior;
	nod *st, *dr; } *nil = new nod{0, (int)-2e9, (int)2e9, (int)2e9, 0, nullptr, nullptr };

nod *mod_fiu(nod *baza, const int care, nod *fiu){
	(care ? baza->dr : baza->st) = fiu;
	baza->big	= max({baza->val, baza->st->big  , baza->dr->big  });
	baza->small = min({baza->val, baza->st->small, baza->dr->small});
	baza->diff	= min({(ll)baza->val - baza->st->big, (ll)baza->dr->small - baza->val, (ll)baza->st->diff , (ll)baza->dr->diff });
	return baza; };

nod *join(nod *st, nod *dr){
	return st == nil ? dr : dr == nil ? st :
		(st->prior > dr->prior) ? mod_fiu(st, 1, join(st->dr, dr)) :
								  mod_fiu(dr, 0, join(st, dr->st)); }

pair<nod*, nod*> split(nod *n, const int mid){
	pair<nod*, nod*> tmp;
	return (n->big < mid) ? make_pair(n, nil) : (n->small >= mid) ? make_pair(nil, n) :
		(n->val < mid) ? (tmp = split(n->dr, mid), make_pair(mod_fiu(n, 1, tmp.first), tmp.second)) :
						 (tmp = split(n->st, mid), make_pair(tmp.first, mod_fiu(n, 0, tmp.second))); }

tuple<nod*, nod*, nod*> split_around(nod *n, const int mid){
	auto tmp = split(n, mid), tmp_ = split(tmp.second, mid+1);
	return make_tuple(tmp.first, tmp_.first, tmp_.second); }

nod *triple_join(nod *a, nod *b, nod*c){
	return join(join(a, b), c); }

nod *rad = nil;

ifstream f("zeap.in");
ofstream g("zeap.out");

int x;

void insert_query(){
	f >> x;
	auto tmp = split_around(rad, x);
	rad = triple_join(get<0>(tmp),
		(get<1>(tmp) == nil ? new nod { x, x, x, (int)2e9, rand(), nil, nil } : get<1>(tmp)),
		get<2>(tmp)); }

void delete_query(){
	f >> x;
	auto tmp = split_around(rad, x);
	if(get<1>(tmp) == nil) g << -1 << '\n';
	else delete get<1>(tmp);
	rad = join(get<0>(tmp), get<2>(tmp)); }

void search_query(){
	f >> x;
	auto tmp = split_around(rad, x);
	g << (get<1>(tmp) != nil) << '\n';
	rad = triple_join(get<0>(tmp), get<1>(tmp), get<2>(tmp)); }

void max_diff_query(){
	g << (rad->big <= rad->small ? -1 : rad->big - rad->small) << '\n'; }

void min_diff_query(){
	g << (rad->big <= rad->small ? -1 : rad->diff) << '\n'; }

map<string, void (*)()> mp {
	{"I"  , &insert_query },
	{"S"  , &delete_query },
	{"C"  , &search_query },
	{"MAX", &max_diff_query },
	{"MIN", &min_diff_query } };

int main(){
	srand(time(nullptr));
	for(string str; f >> str; ) mp[str]();
	return 0; }