Cod sursa(job #2603739)

Utilizator bogdi1bogdan bancuta bogdi1 Data 20 aprilie 2020 19:07:44
Problema Zeap Scor 80
Compilator cpp-32 Status done
Runda Arhiva de probleme Marime 4.29 kb
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
struct Treap
{
    Treap *left,*right;
    int q;
    int maxx,minn;
    int key;
    int pr;
    Treap(int key, int pr)
    {
        left=nullptr;
        right=nullptr;
        q=2000000000;
        if(key!=0){
            maxx=key;
            minn=key;
        }
        else{
            maxx=-2000000000;
            minn=2000000000;
        }
        this->key=key;
        this->pr=pr;
    }
} *nil, *root;
void init()
{
    srand(96383595);
    root=nil=new Treap(0, -1);
}
void update(Treap* treap)
{
    if(treap==nil)
        return;
    treap->maxx=max(treap->key, max(treap->left->maxx, treap->right->maxx));
    treap->minn=min(treap->key, min(treap->left->minn, treap->right->minn));
    treap->q=min(min(treap->left->q, treap->right->q), min(treap->key-treap->left->maxx, treap->right->minn-treap->key));
    if(treap->left!=nil)
        treap->q=min(treap->q, treap->key-treap->left->maxx);
    if(treap->right!=nil)
        treap->q=min(treap->q, treap->right->minn-treap->key);
}
pair<Treap*, Treap*> split(Treap* treap, int key)
{
    if(treap==nil)
        return make_pair(nil, nil);
    pair<Treap*, Treap*> ans;
    if(key<treap->key){
        ans=split(treap->left, key);
        treap->left=ans.second;
        ans.second=treap;
    }
    else{
        ans=split(treap->right, key);
        treap->right=ans.first;
        ans.first=treap;
    }
    update(treap);
    return ans;
}
Treap* join(Treap*  left, Treap *right)
{
    if(left==nil)
        return right;
    if(right==nil)
        return left;
    if(left->pr>right->pr){
        left->right=join(left->right, right);
        update(left);
        return left;
    }
    else{
        right->left=join(left, right->left);
        update(right);
        return right;
    }
}
Treap* add(Treap* treap, int key, int pr)
{
    if(pr>treap->pr){
        pair<Treap*, Treap*> aux=split(treap, key);
        treap=new Treap(key, pr);
        treap->left=aux.first;
        treap->right=aux.second;
        update(treap);
        return treap;
    }
    if(key<treap->key)
        treap->left=add(treap->left, key, pr);
    else
        treap->right=add(treap->right, key, pr);
    update(treap);
    return treap;
}
bool exist(Treap* treap, int key)
{
    if(treap==nil)
        return 0;
    if(key==treap->key)
        return 1;
    if(key<treap->key)
        return exist(treap->left, key);
    else
        return exist(treap->right, key);
}
Treap* del(Treap* treap, int key)
{
    if(treap->key==key){
        Treap* aux=treap;
        treap=join(treap->left, treap->right);
        delete aux;
        update(treap);
        return treap;
    }
    if(key<treap->key)
         treap->left=del(treap->left, key);
    else
        treap->right=del(treap->right, key);
    update(treap);
    return treap;
}
int main()
{   freopen("zeap.in", "r", stdin);
    freopen("zeap.out", "w", stdout);
    char c;
    int x;
    init();
    while(scanf("%c", &c)==1){
        if(c=='I'){
            scanf("%d\n", &x);
            if(exist(root, x)==0)
                root=add(root, x, rand());
        }
        else{
            if(c=='S'){
                scanf("%d\n", &x);
                if(exist(root, x)==0)
                    printf("-1\n");
                else
                    root=del(root, x);
            }
            else{
                if(c=='C'){
                    scanf("%d\n", &x);
                    printf("%d\n", exist(root, x));
                }
                else{
                    scanf("%c", &c);
                    if(c=='A'){
                        if(root->maxx-root->minn==0 || root->maxx==-2000000000)
                            printf("-1\n");
                        else
                            printf("%d\n", root->maxx-root->minn);
                    }
                    else{
                        if(root->q<1000000000)
                            printf("%d\n", root->q);
                        else
                            printf("-1\n");
                    }
                    fgetc(stdin);
                    fgetc(stdin);
                }
            }
        }
    }
    return 0;
}