Cod sursa(job #1786877)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 23 octombrie 2016 20:02:47
Problema Zeap Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.97 kb
#include <bits/stdc++.h>
using namespace std;

const int INF = 2e9;

struct T {
    int val, mx, mn, df, pr, siz;
    T *st, *dr; } *nil;

void reset(T *arg) {
    arg->siz = arg->st->siz + arg->dr->siz + 1;

    arg->mx = arg->val;
    arg->mn = arg->val;
    arg->df = INF;

    if(arg->st != nil) {
        arg->df = min(arg->df, arg->st->df); // :*
        arg->df = min(arg->df, arg->val - arg->st->mx);
        arg->mx = max(arg->mx, arg->st->mx);
        arg->mn = min(arg->mn, arg->st->mn); }

    if(arg->dr != nil) {
        arg->df = min(arg->df, arg->dr->df);
        arg->df = min(arg->df, arg->dr->mn - arg->val);
        arg->mx = max(arg->mx, arg->dr->mx);
        arg->mn = min(arg->mn, arg->dr->mn); }  }

T *find(T *nod, int val) {
    if(nod->val == val) return nod;
    if(nod == nil) return nil;
    if(nod->val < val) return find(nod->dr, val);
    if(nod->val > val) return find(nod->st, val); }

pair<T*, T*> split(T *nod, int val) {
    if(nod == nil) return make_pair(nil, nil);

    if(nod->val < val) {
        auto tmp = split(nod->dr, val);
        nod->dr = tmp.first;
        reset(nod);
        return make_pair(nod, tmp.second); }
    else {
        auto tmp = split(nod->st, val);
        nod->st = tmp.second;
        reset(nod);
        return make_pair(tmp.first, nod); } }

T *join(T *a, T *b) {
    if(a == nil) return b;
    if(b == nil) return a;

    if(a->pr >= b->pr) {
        a->dr = join(a->dr, b);
        reset(a);
        return a; }
    else {
        b->st = join(a, b->st);
        reset(b);
        return b; } }

T *join3(T *a, T *b, T *c) {
    return join(join(a, b), c); }

tuple<T*, T*, T*> split3(T *nod, int a, int b) {
    auto x = split(nod, b);
    auto y = split(x.first, a);
    return make_tuple(y.first, y.second, x.second); }

T *insert(T *nod, int val) {
    auto tmp = split3(nod, val-1, val+1);
    return join3(get<0>(tmp), new T {val, val, val, INF, rand(), 1, nil, nil}, get<2>(tmp)); }

T *remove(T *nod, int val) {
    auto tmp = split3(nod, val-1, val+1);
    return join3(get<0>(tmp), nil, get<2>(tmp)); }

int main(void) {
    ifstream fi("zeap.in");
    ofstream fo("zeap.out");
    string line, cmd;
    int arg;
    T *root, *tmp;

    srand(time(NULL));
    nil = new T {0, 0, 0, 0, -INF, 0, 0x00, 0x00};
    root = nil;

    while(getline(fi, line)) {
        istringstream ss(line);
        ss >> cmd;

        if(cmd=="MIN") {
            fo << ((root->siz < 2) ? -1 : (root->df)) << '\n'; }

        if(cmd=="MAX") {
            fo << ((root->siz < 2) ? -1 : (root->mx - root->mn)) << '\n'; }

        if(cmd=="C") {
            ss >> arg;
            tmp = find(root, arg);
            fo << ((tmp == nil) ? 0 : 1) << '\n'; }

        if(cmd=="I") {
            ss >> arg;
            if(find(root, arg) == nil)
                root = insert(root, arg); }

        if(cmd=="S") {
            ss >> arg;
            if(find(root, arg) == nil)
                fo << "-1\n";
            else
                root = remove(root, arg); } }

    return 0; }