Cod sursa(job #2802960)

Utilizator Tudor06MusatTudor Tudor06 Data 19 noiembrie 2021 10:02:17
Problema Zeap Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.48 kb
#include <bits/stdc++.h>

using namespace std;

const int INF = 1e9;

struct Treap {
  int value;
  int siz;
  long long priority;
  int mindif;
  int maxim;
  int minim;
  Treap* left;
  Treap* right;
};

Treap* emptyTreap = new Treap {
  0,
  0,
  -1,
  INF,
  0,
  INF,
  NULL,
  NULL
};

int modul( int x ) {
    if ( x > 0 )
        return x;
    return -x;
}
Treap* recomputeTree( Treap* root, Treap* new_left, Treap* new_right ) {
    root->left = new_left;
    root->right = new_right;
    root->siz = root->left->siz + root->right->siz + 1;
    root->maxim = max( max( root->left->maxim, root->right->maxim ), root->value );
    root->minim = min( min( root->left->minim, root->right->minim ), root->value );

    int md = root->mindif;
    if ( root->left != emptyTreap ) {
        md = min( root->left->mindif, root->value - root->left->value );
    }
    if ( root->right != emptyTreap ) {
        md = min( min( root->right->mindif, root->right->value - root->value ), md );
    }
    root->mindif = md;
//    root->mindif = min( root->mindif, min( min( root->left->mindif, root->right->mindif ),
//                                           min( root->value - root->left->value,
//                                                root->right->value - root->value ) ) );
    return root;
}
pair <Treap*, Treap*> split( Treap* root, int value ) {
    if ( root == emptyTreap ) {
        return make_pair( emptyTreap, emptyTreap );
    }
    if ( value < root->value ) {
        auto p = split( root->left, value );

        return make_pair( p.first, recomputeTree( root, p.second, root->right ) );
    }
    if ( value >= root->value ) {
        auto p = split( root->right, value );
        return make_pair( recomputeTree( root, root->left, p.first ), p.second );
    }
}
Treap* merge_( Treap* first, Treap* second ) {
    if ( first == emptyTreap )
        return second;
    if ( second == emptyTreap )
        return first;
    if ( second->priority < first->priority )
        return recomputeTree( first, first->left, merge_( first->right, second ) );
    if ( second->priority >= first->priority )
        return recomputeTree( second, merge_( first, second->left ), second->right );
}
Treap* insert______( Treap* root, Treap* value ) {
    if ( root == emptyTreap ) {
        return value;
    }
    if ( root->priority < value->priority ) {
        auto p = split( root, value->value );
        return recomputeTree( value, p.first, p.second );
    }
    if ( root->value < value->value )
        return recomputeTree( root, root->left, insert______( root->right, value ) );
    if ( root->value >= value-> value )
        return recomputeTree( root, insert______( root->left, value ), root->right );
}
Treap* insert_( Treap* root, int value ) {
    Treap* newValue = new Treap {
        value,
        1,
        ( (long long)rand() << 31 ) ^ rand(),
        INF,
        0,
        INF,
        emptyTreap,
        emptyTreap,
    };
    ///cout << newValue->value << endl;
    return insert______( root, newValue );
}
bool search_( Treap* root, int value ) {
    if ( root == emptyTreap )
        return false;
    if ( root->value == value )
        return true;
    if ( root->value < value )
        return search_( root->right, value );
    if ( root->value > value );
        return search_( root->left, value );
}
Treap* delete_( Treap* root, int value ) {
    auto p = split( root, value );
    auto p2 = split( p.first, value - 1 );
    return merge_( p2.first, p.second );
}

int main() {
    ifstream fin( "zeap.in" );
    ofstream fout( "zeap.out" );

    Treap* root = emptyTreap;
    string s;
    while ( fin >> s ) {
        int a;
        if ( s == "I" ) {
            fin >> a;
            root = insert_( root, a );
            ///cout << root->value << endl;
        } else if ( s == "S" ) {
            fin >> a;
            if ( search_( root, a ) )
                root = delete_( root, a );
            else
                fout << -1 << '\n';
        } else if ( s == "C" ) {
            fin >> a;
            fout << search_( root, a ) << '\n';
        } else if ( s == "MAX" ) {
            if ( root->siz >= 2 )
                fout << root->maxim - root->minim << '\n';
            else
                fout << -1 << '\n';
        } else
            if ( root->siz >= 2 ) {
                fout << root->mindif << '\n';
            } else
                fout << -1 << '\n';
    }
}