Cod sursa(job #2507862)

Utilizator ArdeleanOficialAlexandru ArdeleanOficial Data 10 decembrie 2019 22:24:51
Problema Zeap Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.02 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("zeap.in");
ofstream fout("zeap.out");

mt19937 rnd((long long)(new char));

typedef struct Treap * Arbore;
typedef pair < Arbore, Arbore > Paa;

Arbore NIL;

struct Treap {
    int minim, maxim, dmin, val, nl;
    long long prio;
    Arbore st, dr;///st <= val, dr > val

    void recalc() {///Probabil ca va fi useless odata ce o sa am build()
        nl = 1 + st->nl + dr->nl;
    }

//    Treap(int val = 0) : minim(val), maxim(val), dmin(1e9 + 7), val(val), nl(0), prio(rnd()), st(NIL), dr(NIL) { }
};

Arbore cplusplusehomosexual(int val) {
    return new Treap {
        val,
        val,
        (int)2e9 + 7,
        val,
        0,
        rnd(),
        NIL,
        NIL,
    };
}

Arbore build(Arbore rad, Arbore newst, Arbore newdr) {
    int newSize(1 + newst->nl + newdr->nl);
    rad->minim = min(rad->val, min(newst->minim, newdr->minim));
    rad->maxim = max(rad->val, max(newst->maxim, newdr->maxim));
    rad->dmin = min((int)min(min((long long)rad->val - (long long)newst->maxim, (long long)newdr->minim - (long long)rad->val), (long long)2e9 + 7), min(newst->dmin, newdr->dmin));
    rad->nl = newSize;
    rad->st = newst;
    rad->dr = newdr;
//    return rad = new Treap {
//        min(rad->val, min(st->minim, dr->minim)),
//        max(rad->val, max(st->maxim, dr->maxim)),
//        min(min(rad->val - st->maxim, dr->minim - rad->val), min(st->dmin, dr->dmin)),
//        rad->val,
//        newSize,
//        rad->prio,
//        st,
//        dr,
//    };
    return rad;
}
Arbore Join(Arbore a, Arbore b);
Paa Split(Arbore rad, int val);///<=val->first;>=val->second
Arbore Insert(Arbore rad, int val);///evident ne garantam ca nu exista
Arbore Sterge(Arbore rad, int val);///aici ne garantam ca exista
bool Cauta(Arbore rad, int val);///1->e
int MaxDiff(Arbore rad) {
    if (rad->nl < 2)
        return -1;
    return rad->maxim - rad->minim;
}
int MinDiff(Arbore rad) {
    return rad->dmin;
}
void Dump(Arbore rad, int tata = 0) {
    if (rad == NIL)
        return;
    if (rad->prio < rad->st->prio || rad->prio < rad->dr->prio)
        fout << "\nAi Busit prioritatile\n";
    Dump(rad->st, rad->val);
    fout << "val : " << rad->val << " tata : " << tata << " dmin : " << rad->dmin << ' ';
    Dump(rad->dr, rad->val);
}

int main()
{
    NIL = new Treap();
    NIL->minim = 2e9 + 7;
    NIL->maxim = -2e9 + 7;
    NIL->nl = 0;
    NIL->prio = 0;
    NIL->dmin = 2e9 + 7;
    NIL->val = 0;

    Arbore eu = NIL;
    string s;
    int val;
    while (fin >> s) {
        if (s == "MAX") {
            if (eu->nl < 2)
                fout << "-1\n";
            else
                fout << MaxDiff(eu) << '\n';
        }
        else if (s == "MIN") {
            if (eu->nl < 2)
                fout << "-1\n";
            else
                fout << MinDiff(eu) << '\n';
        }
        else if (s == "I") {
            fin >> val;
            if (Cauta(eu, val))
                continue;
            eu = Insert(eu, val);
//            fout << "Operatie : " << s << ' ' << val << '\n';
//            fout << "Structura Treapului :\n";
//            Dump(eu);
//            fout << '\n';
        }
        else if (s == "S") {
            fin >> val;
            if (!Cauta(eu, val)) {
                fout << "-1\n";
                continue;
            }
            eu = Sterge(eu, val);
//            fout << "Operatie : " << s << ' ' << val << '\n';
//            fout << "Structura Treapului :\n";
//            Dump(eu);
//            fout << '\n';
        }
        else if (s == "C") {
            fin >> val;
            fout << Cauta(eu, val) << '\n';
        }
    }
    return 0;
}

Arbore Join(Arbore a, Arbore b) {///val lui a < val lui b ca altfel am belito
    if (a == NIL)
        return b;
    if (b == NIL)
        return a;
    if (a->prio > b->prio) {///a sus
        Arbore ans = Join(a->dr, b);
        return build(a, a->st, ans);
    }
    else {
        Arbore ans = Join(a, b->st);
        return build(b, ans, b->dr);
    }
}

Paa Split(Arbore rad, int val) {
    if (rad == NIL)
        return {NIL, NIL};
    if (val >= rad->val) {
        Paa ans = Split(rad->dr, val);
        return {build(rad, rad->st, ans.first), ans.second};
    }
    else {
        Paa ans = Split(rad->st, val);
        return {ans.first, build(rad, ans.second, rad->dr)};
    }
}

Arbore Insert(Arbore rad, int val) {///rucu-tucu raca-taca
    Paa ans = Split(rad, val);
    return Join(Join(ans.first, cplusplusehomosexual(val)), ans.second);
}

Arbore Sterge(Arbore rad, int val) {
    Paa ans1 = Split(rad, val - 1);
    Paa ans2 = Split(ans1.second, val);
    return Join(ans1.first, ans2.second);
}

bool Cauta(Arbore rad, int val) {
    if (rad == NIL)
        return 0;
    if (rad->val == val)
        return 1;
    if (rad->val >= val)
        return Cauta(rad->st, val);
    return Cauta(rad->dr, val);///if (rad->val < val)
}