Cod sursa(job #2730084)

Utilizator adiaioanaAdia R. adiaioana Data 25 martie 2021 19:11:08
Problema Zeap Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.81 kb
#include <fstream>
#include <random>
#include <chrono>
#define elif else if
using namespace std;
ifstream cin("zeap.in");
ofstream cout("zeap.out");
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
struct treap{
    treap *left, *right;
    int mini, maxi, mindif, key,pri;

    treap(int prior){
        this->left= this->right= NULL;
        this->mini=INT_MAX;
        this->maxi=0;
        this->key=-1;
        this->pri=prior;
    }
};
typedef treap* ptreap;
ptreap T=new treap(rng());
ptreap nil=new treap(0);

int MIN(int x,int y,int z)
{
    return min(min(x,y),z);
}


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);
    cin.tie();

    while(cin>>op){
        if(op=='I'){
            cin>>x;
            _insert(T,x);
        }
        elif (op=='S')
        {
            cin>>x;
            ex=-1;
            _erase(T,x,ex);
            if(ex)
                cout<<-1<<'\n';
        }
        elif (op=='M')
        {
            cin>>ch;
            if(ch=='A')
                x=((T->maxi)-(T->mini));
            else x=(T->mindif);
            //x=(ch=='A')?(T->maxi-T->mini):(T->mindif);
            cin>>ch;
            cout<<x<<'\n';
        }
        elif (op=='C')
        {
            cin>>x;
            ex=0;
            _search(T,x,ex);
            cout<<ex<<'\n';
        }
        cin.get();
    }
    return 0;
}

void _split(ptreap root, int val, ptreap &left, ptreap &right)
{
    if(root==nullptr)
        left=right=NULL;
    elif (val<=root->key)
    {
        _split(root->left, val, left, root->left);
        right=root;
    }
    elif (val>root->key)
    {
        _split(root->right, val, root->right, right);
        left=root;
    }
    _update(root);
}

void _merge(ptreap &root, ptreap left, ptreap right)
{
    if(left==NULL || right==NULL)
        root=(left!=NULL)?left:right;
    elif (left->pri >= right->pri)
    {
        if((left->right)!=NULL)
            _merge(left->right, left->right, right);
        root=left;
    }
    elif (right->pri >left->pri)
    {
        if((right->left)!=NULL)
            _merge(right->left, left, right->left);
        root=right;
    }
    _update(root);
}
void _update(ptreap &root)
{
    if(root==nullptr)
        return ;
    if(!((root->left)==nullptr))
    {
        root->mini=min(root->mini, root->left->mini);
        root->mindif=MIN(root->mindif, (root->left)->mindif, root->key- (root->left)->maxi);
    }
    if(!((root->right)==nullptr))
    {
        ptreap r=root->right;
        root->maxi=max(root->maxi, r->maxi);
        root->mindif=MIN(root->mindif, r->mindif, r->mini- root->key);
    }
    return ;
}

void _insert(ptreap &root, int val)
{
    ptreap elem=new treap(rng());
    elem->key=elem->maxi=elem->mini=val;
    ptreap l,r;

    _split(root, val, l, r);
    _merge(l, l, elem);
    _merge(root, l, r);
}
void _erase(ptreap &root, int val, int &ans)
{
    if(root==NULL)
        return;
    elif(root->key==val)
    {
        _merge(root, root->left, root->right);
        ans=0;
    }
    elif (root->key<=val)
        _erase(root->left, val, ans);
    elif (root->key>val)
        _erase(root->right, val, ans);
    _update(root);
}

void _search(ptreap root, int val, int &ex)
{
    if(root==NULL)
        return ;
    elif (root->key==val)
        ex=1;
    elif (root->key<val)
        _search(root->left, val, ex);
    elif (root->key>val)
        _search(root->right, val, ex);
}