Cod sursa(job #1806403)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 15 noiembrie 2016 11:57:57
Problema Zeap Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.54 kb
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO

class treap
{
private:
    struct _node
    {
        int vl, p;
        _node *l, *r;
        int mn, mx, mndf, mxdf;

        _node()
        {
            vl = p = 0;
            l = r = 0;
            mx = mxdf = 0;
            mn = mndf = 1 << 30;
        }
    } *R, *nil;

    void recalc(_node *&R)
    {
        if(R == nil)    return;
        R -> mn = R -> mx = R -> vl;
        R -> mndf = 1 << 30;
        if(R -> l != nil)
        {
            R -> mn = R -> l -> mn;
            R -> mndf = min(R -> mndf, R -> l -> mndf);
            R -> mndf = min(R -> mndf, R -> vl - R -> l -> mx);
        }
        if(R -> r != nil)
        {
            R -> mx = R -> r -> mx;
            R -> mndf = min(R -> mndf, R -> r -> mndf);
            R -> mndf = min(R -> mndf, R -> r -> mn - R -> vl);
        }
        R -> mxdf = R -> mx - R -> mn;
    }

public:
    void init()
    {
        nil = new _node();
        nil -> l = nil -> r = nil;
        R = nil;
    }

    _node* merge(_node *&L, _node *&R)
    {
        if(L == nil)    return R;
        if(R == nil)    return L;
        if(L -> p > R -> p)
        {
            L -> r = merge(L -> r, R);
            recalc(L);
            return L;
        }
        else
        {
            R -> l = merge(L, R -> l);
            recalc(R);
            return R;
        }
        return nil;
    }

    pair<_node*, _node*> split(_node *&R, int val)
    {
        if(R == nil)
            return {nil, nil};
        pair <_node*, _node*> ans;
        if(val <= R -> vl)
        {
            ans = split(R -> l, val);
            R -> l = ans.second;
            ans.second = R;
        }
        else
        {
            ans = split(R -> r, val);
            R -> r = ans.first;
            ans.first = R;
        }
        recalc(R);
        return ans;
    }

    void insert(int x)
    {
        _node *N = new _node;
        N -> vl = N -> mn = N -> mx = x;
        N -> p = rand();
        N -> l = N -> r = nil;

        auto ans = split(R, x);
        auto aux = merge(N, ans.second);
        R = merge(ans.first, aux);
        recalc(R);
    }

    int search(_node *&R, int x)
    {
        if(R -> vl == x)    return 1;
        if(R == nil)    return 0;
        if(R -> vl > x) return search(R -> l, x);
        if(R -> vl < x) return search(R -> r, x);
        return 0;
    }

    int search(int x)
    {
        return search(R, x);
    }

    int erase(int x)
    {
        _node *l, *m, *r, *mr;
        auto aux = split(R, x);
        l = aux.first;
        mr = aux.second;
        aux = split(mr, x + 1);
        r = aux.second;
        m = aux.first;
        R = merge(l, r);
        recalc(R);
        if(m == nil)    return 0;
        return 1;
    }

    int getMinDiff()
    {
        if(R -> mndf == 1 << 30)    return -1;
        return R -> mndf;
    }

    int getMaxDiff()
    {
        if(R -> mxdf == 0)  return -1;
        return R -> mxdf;
    }

}trp;

int main()
{
    #ifdef FILE_IO
    freopen("zeap.in", "r", stdin);
    freopen("zeap.out", "w", stdout);
    #endif

    srand(time(0));

    trp.init();
    while(1)
    {
        char ch = getchar();
        if(ch == 'M')
        {
            ch = getchar();
            ch = getchar();
            int ans = 0;
            if(ch == 'X')
                ans = trp.getMaxDiff();
            else
                ans = trp.getMinDiff();
            printf("%d\n", ans);
            ch = getchar();
        }
        else if(ch == 'I' || ch == 'S' || ch == 'C')
        {
            char op = ch;
            ch = getchar();
            ch = getchar();
            int smn = 1;
            if(ch == '-')
            {
                ch = getchar();
                smn = -1;
            }
            int x = 0;
            while('0' <= ch && ch <= '9')
            {
                x = x * 10 + ch - '0';
                ch = getchar();
            }
            x *= smn;

            if(op == 'I')
                trp.insert(x);
            else if(op == 'S')
            {
                int ok = trp.erase(x);
                if(!ok)
                    printf("-1\n");
            }
            else
            {
                int ok = trp.search(x);
                printf("%d\n", ok);
            }
        }
        else
            break;

        if(ch != '\n')  break;
    }

    return 0;
}