Cod sursa(job #1855704)

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

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({baza->val - baza->st->big, baza->dr->small - baza->val, baza->st->diff , 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; }