Cod sursa(job #2730085)

Utilizator adiaioanaAdia R. adiaioana Data 25 martie 2021 19:11:39
Problema Zeap Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.81 kb
#include <bits/stdc++.h>
#define elif else if
#define INF 1000000001
using namespace std;
ifstream fin("zeap.in");
ofstream fout("zeap.out");

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct treap
{
    int val, pri;
    int maxi,mini,mind;
    treap *l=nullptr, *r=nullptr;

    treap(int val)
    {
        this->val=val;
        maxi=val;
        mini=val;
        mind=INF;

        pri=rng();
    }
};

typedef treap* ptreap;
ptreap T=nullptr;

void _erase(ptreap &root, int val, int &ans);
void _split(ptreap root, int val, ptreap &left, ptreap &right);
void _merge(ptreap &root, ptreap left, ptreap right);
void _update(ptreap &root);
void _insert(ptreap &root,int val);
void _search(ptreap root, int val, int &ex);

char op, ch;
int main()
{
    int x, ex;
    ios_base::sync_with_stdio(false);
    fin.tie();

    while(fin>>op){
        if(op=='I'){
            fin>>x;
            _insert(T,x);

        }
        elif (op=='S')
        {
            fin>>x;
            ex=-1;
            _erase(T,x,ex);
            if(ex)
                fout<<-1<<'\n';
        }
        elif (op=='M')
        {
            fin>>ch;
            if(ch=='A')
            {
                if(!T || T->mini==T->maxi)
                    x=-1;
                else x=T->maxi- T->mini;
            }
            else
            {
                if(!T || T->mind==INF)
                    x=-1;
                else x=T->mind;
            }
            fin>>ch;
            fout<<x<<'\n';
        }
        elif (op=='C')
        {
            fin>>x;
            ex=0;
            _search(T,x,ex);
            fout<<ex<<'\n';
        }
        fin.get();
    }
    return 0;
}

void _split(ptreap root, int val, ptreap &left, ptreap &right)
{
    if(!root){
        left=right=nullptr;
        return ;
    }
    elif (val<root->val)
    {
        right=root;
        _split(root->l, val, left, root->l);
    }
    elif (val>=root->val)
    {
        left=root;
        _split(root->r, val, root->r, right);
    }
    _update(root);
}

void _merge(ptreap &root, ptreap left, ptreap right)
{
    if(!right){
        root=left;
        return ;
    }
    elif (!left){
        root=right;
        return ;
    }
    elif (left->pri > right->pri)
    {
        root=left;
        _merge(root->r, root->r, right);
    }
    elif (right->pri >= left->pri)
    {
        root=right;
        _merge(root->l, left, root->l);
    }
    _update(root);
}

void _update(ptreap &root)
{
    if(!root)
        return ;
    root->maxi=root->mini=root->val;
    root->mind=INF;
    if((root->l))
    {
        root->mini=min(root->mini, (root->l)->mini);
        root->mind=min(root->mind, (root->l)->mind);
        root->mind=min(root->mind, root->val- (root->l)->maxi);
    }
    if((root->r))
    {
        root->maxi=max(root->maxi, (root->r)->maxi);
        root->mind=min(root->mind, (root->r)->mind);
        root->mind=min(root->mind, (root->r)->mini- root->val);
    }
}

void _insert(ptreap &root,int val)
{
    ptreap l,r,mij;

    _split(root,val-1, l, r);
    _split(r, val, mij, r);
    if(!mij)
        mij=new treap(val);

    _merge(l,l,mij);
    _merge(root,l,r);
}
void _erase(ptreap &root, int val, int &ans)
{
    ptreap l,r,mij;

    _split(root, val-1, l, r);
    _split(root, val, mij, r);

    if(!mij)
    {
        ans=0;
        _merge(root,l,r);
        return ;
    }

    _merge(root,l,r);
}

void _search(ptreap root, int val, int &ex)
{
    ptreap l,r,mij;
    _split(root, val-1, l, r);
    _split(root, val, mij, r);
    if(mij){
        ex=1;
        _merge(l,l,mij);
        _merge(root,l,r);
        return ;
    }

    _merge(l,l,mij);
    _merge(root,l,r);
}