Cod sursa(job #2188663)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 27 martie 2018 12:30:23
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 6.75 kb
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;

class Treap
{
public:
    struct Node
    {
        int pr, val;
        int sz, mn, mx, dif;
        Node *l, *r;

        Node()
        {
            pr = val = sz = mn = mx = dif = 0;
            l = r = 0;
        }

        Node(int _pr, int _val, Node *_l, Node *_r)
        {
            pr = _pr, val = _val;
            l = _l; r = _r;
            sz = 1;
            mn = mx = val;
            dif = 1 << 30;
        }
    };
    Node *R, *nil;

    int newPriority()
    {
        int msk = (1 << 9) - 1;
        int x = rand() & msk;
        int y = rand() & msk;
        int z = rand() & msk;
        return (x | (y << 9) | (z << 18));
    }

    void remake(Node *&T)
    {
        if(T == nil)    return;
        T -> sz = T -> l -> sz + 1 + T -> r -> sz;
        T -> mn = T -> val;
        if(T -> l != nil)   T -> mn = T -> l -> mn;
        T -> mx = T -> val;
        if(T -> r != nil)   T -> mx = T -> r -> mx;

        T -> dif = 1 << 30;
        if(T -> l != nil)
            T -> dif = min(T -> l -> dif, T -> val - T -> l -> mx);
        if(T -> r != nil)
            T -> dif = min( {T -> dif, T -> r -> dif, T -> r -> mn - T -> val} );
    }

    Node* join(Node *&l, Node *&r)
    {
        if(l == nil)    return r;
        if(r == nil)    return l;

        if(l -> pr > r -> pr)
        {
            l -> r = join(l -> r, r);
            remake(l);
            return l;
        }
        else
        {
            r -> l = join(l, r -> l);
            remake(r);
            return r;
        }

        return nil;
    }

    pair<Node*, Node*> split(Node *&T, int val)
    {
        if(T == nil)    return {nil, nil};

        if(T -> val >= val)
        {
            auto aux = split(T -> l, val);
            T -> l = aux.second;
            aux.second = T;
            remake(T);
            return aux;
        }
        else
        {
            auto aux = split(T -> r, val);
            T -> r = aux.first;
            aux.first = T;
            remake(T);
            return aux;
        }

        return {nil, nil};
    }

    void init()
    {
        nil = new Node();
        nil -> l = nil -> r = nil;
        R = nil;
    }

    void insert(int val)
    {
        Node *nd = new Node(newPriority(), val, nil, nil);
        auto lr = split(R, val);
        Node *lm = join(lr.first, nd);
        R = join(lm, lr.second);
    }

    void erase(int val)
    {
        auto lmr = split(R, val);
        auto mr = split(lmr.second, val + 1);
        Node *nd = join(mr.first -> l, mr.first -> r);
        Node *lm = join(lmr.first, nd);
        R = join(lm, mr.second);
    }

    int getsize(int st, int dr)
    {
        if(st > dr) return 0;
        auto lmr = split(R, st);
        auto mr = split(lmr.second, dr + 1);
        int cnt = mr.first -> sz;
        Node *lm = join(lmr.first, mr.first);
        R = join(lm, mr.second);
        return cnt;
    }

    int getmin()
    {
        if(R -> sz == 0)    return -1;
        return R -> mn;
    }

    int getmax()
    {
        if(R -> sz == 0)    return -1;
        return R -> mx;
    }

    int getdifmin()
    {
        if(R -> sz < 2) return -1;
        return R -> dif;
    }

    int getdifmax()
    {
        if(R -> sz < 2) return -1;
        return R -> mx - R -> mn;
    }
};
Treap trp;

set<pii> itv;
char s[25];
vector<pii> aux;

pair<pii, pii> update_interval(int st, int dr)
{
    pii lft = {1 << 30, -(1 << 30)}, rgt = {1 << 30, -(1 << 30)};
    auto it1 = itv.lower_bound({st, 0});
    int l = st, r = dr;
    if(it1 != itv.begin())
    {
        it1--;
        if((*it1).second < st)  it1++;
    }
    auto it2 = itv.lower_bound({dr + 1, 0});
    for(auto it = it1; it != it2; it++)
        trp.erase((*it).second - (*it).first);
    if(it1 != it2)
    {
        it2--;
        lft = *it1;
        rgt = *it2;
        it2++;
    }
    itv.erase(it1, it2);
    return {lft, rgt};
}

void insert_interval(int st, int dr)
{
    auto itvs = update_interval(st, dr);
    int lft = min(st, itvs.first.first);
    int rgt = max(dr, itvs.second.second);
    trp.insert(rgt - lft);
    itv.insert({lft, rgt});
}

void erase_interval(int st, int dr)
{
    auto itvs = update_interval(st, dr);
    if(itvs.first.first <= st)
    {
        trp.insert(st - itvs.first.first);
        itv.insert({itvs.first.first, st});
    }
    if(dr <= itvs.second.second)
    {
        trp.insert(itvs.second.second - dr);
        itv.insert({dr, itvs.second.second});
    }
}

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

    srand(time(0));
    trp.init();

    char s[25];
    map<int, int> mp;
    while( scanf("%s", s + 1) == 1 )
    {
        if(s[1] == 'I')
        {
            int x;
            scanf("%d\n", &x);
            if(mp[x] > 0)   continue;
            trp.insert(x);
            mp[x]++;
        }
        else if(s[1] == 'S')
        {
            int x;
            scanf("%d\n", &x);
            if(mp[x] == 0)
            {
                printf("-1\n");
                continue;
            }
            trp.erase(x);
            mp[x]--;
        }
        else if(s[1] == 'C')
        {
            int x;
            scanf("%d\n", &x);
            int ans = (mp[x] > 0);
            printf("%d\n", ans);
        }
        else if(s[2] == 'A')
        {
            int ans = trp.getdifmax();
            printf("%d\n", ans);
        }
        else if(s[2] == 'I')
        {
            int ans = trp.getdifmin();
            printf("%d\n", ans);
        }
    }

    /*int Q;
    scanf("%d\n", &Q);
    for(int q = 1; q <= Q; q++)
    {
        char op = getchar();
        if(op == '1')
        {
            int st, dr;
            scanf("%d%d\n", &st, &dr);
            insert_interval(st, dr);
        }
        else if(op == '0')
        {
            int st, dr;
            scanf("%d%d\n", &st, &dr);
            erase_interval(st, dr);
        }
        else if(op == '2')
        {
            int st, dr;
            scanf("%d%d\n", &st, &dr);
            printf("%d\n", trp.getsize(st, dr));
        }
        else if(op == 'M')
        {
            scanf("%s\n", s + 1);
            if(s[1] == 'I') printf("%d\n", trp.getmin());
            else if(s[1] == 'A')    printf("%d\n", trp.getmax());
        }
        else if(op == 'D')
        {
            scanf("%s\n", s + 1);
            if(s[6] == 'I') printf("%d\n", trp.getdifmin());
            else if(s[6] = 'A') printf("%d\n", trp.getdifmax());
        }
    }*/

    return 0;
}