Cod sursa(job #2956309)

Utilizator stefan.popescuPopescu Stefan stefan.popescu Data 18 decembrie 2022 23:42:57
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.24 kb
#include <bits/stdc++.h>
#include <iostream>

using namespace std;
const int inf = 1e9;

struct segObj{
    int maxi, mini, ans;
    segObj(int x = 0, int y = inf + 1, int nn = inf + 1) : maxi(x), mini(y), ans(nn) { }
    inline friend segObj operator + (const segObj & s1, const segObj & s2){
        return segObj(max(s1.maxi, s2.maxi), min(s1.mini, s2.mini), min(min(s1.ans, s2.ans), s1.maxi == 0 || s2.maxi == 0 ? inf + 1 : s2.mini - s1.maxi));
    }
};

struct segNode{
    segObj info;
    segNode * ll, * rr;
    segNode(segObj temp = segObj(), segNode * p1 = nullptr, segNode * p2 = nullptr) : info(temp), ll(p1), rr(p2) { }
};

vector <int> nrm;

vector <pair<string, int> > qrs;

class segTree{
private:
    segNode * root;
    const int len = 3e5;
public:
    segTree() : root(nullptr) { }
    void pointInsert(int x){
        insertUtil(root, 1, len, x);
    }
    int pointDelete(int x){
        return deleteUtil(root, 1, len, x);
    }
    int pointFind(int x){
        return findUtil(root, 1, len, x);
    }
    segObj rootInf(){
        return root == nullptr ? segObj() : root -> info;
    }
private:
    int findUtil(segNode * & ptr, int l, int r, int p){
        if(ptr == nullptr || ptr -> info.maxi == 0)
            return 0;
        if(l == r)
            return 1;
        int mij = (l + r) / 2;
        if(p <= mij)
            return findUtil(ptr -> ll, l, mij, p);
        else
            return findUtil(ptr -> rr, mij + 1, r, p);
    }
    int deleteUtil(segNode * & ptr, int l, int r, int p){
        if(ptr == nullptr || ptr -> info.maxi == 0)
            return -1;
        if(l == r){
            ptr -> info = segObj();
            return 0;
        }
        int t = -1;
        int mij = (l + r) / 2;
        if(p <= mij)
            t = deleteUtil(ptr -> ll, l, mij, p);
        else
            t = deleteUtil(ptr -> rr, mij + 1, r, p);
        ptr -> info = (ptr -> ll == nullptr ? ptr -> rr -> info : (ptr -> rr == nullptr ? ptr -> ll -> info : (ptr -> ll -> info + ptr -> rr -> info) ) );
        return t;
    }
    void insertUtil(segNode * & ptr, int l, int r, int p){
        if(ptr == nullptr)
            ptr = new segNode();
        if(l == r){
            ptr -> info = segObj(nrm[p], nrm[p]);
            return;
        }
        int mij = (l + r) / 2;
        if(p <= mij)
            insertUtil(ptr -> ll, l, mij, p);
        else
            insertUtil(ptr -> rr, mij + 1, r, p);
        ptr -> info = (ptr -> ll == nullptr ? ptr -> rr -> info : (ptr -> rr == nullptr ? ptr -> ll -> info : (ptr -> ll -> info + ptr -> rr -> info) ) );
    }   
};

void solve(){
    segTree arb;
    string s;
    while(cin >> s){
        if(s[0] != 'M'){
            int x;
            cin >> x;
            qrs.emplace_back(s, x);
            nrm.push_back(x);
        }
        else{
            qrs.emplace_back(s, 0);
        }
    }
    sort(nrm.begin(), nrm.end());
    nrm.erase(unique(nrm.begin(), nrm.end()), nrm.end());
    nrm.insert(nrm.begin(), 0);

    for(auto &t:qrs){
        string s = t.first;
        int x = t.second;
        if(s[0] != 'M'){
            x = lower_bound(nrm.begin(), nrm.end(), x) - nrm.begin();
            if(s[0] == 'I')
                arb.pointInsert(x);
            else if(s[0] == 'C')
                cout << arb.pointFind(x) << "\n";
            else{
                if(arb.pointDelete(x) == -1)
                    cout << "-1\n";
            }  
        }
        else{
            if(s == "MAX"){
                auto t = arb.rootInf();
                if(t.maxi == 0 || t.maxi == t.mini)
                    cout << "-1\n";
                else
                    cout << t.maxi - t.mini << "\n";
            }
            else{
                auto t = arb.rootInf();
                if(t.maxi == 0 || t.maxi == t.mini)
                    cout << "-1\n";
                else
                    cout << t.ans << "\n";
            }
        }
    }

}

int main(){
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    freopen("zeap.in", "r", stdin);
    freopen("zeap.out", "w", stdout);
    
    int q = 1;
    // cin >> q;
    while(q--){
        solve();
    }

    return 0;
}