Cod sursa(job #1989160)

Utilizator vladttturcuman vlad vladtt Data 6 iunie 2017 11:21:28
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.94 kb
//
//  main.cpp
//  Treaps
//
//  Created by Vlad Turcuman on 30/05/2017.
//  Copyright © 2017 Vlad Turcuman. All rights reserved.
//
#include <fstream>
#include <ctime>
#include <cstdlib>

using namespace std;

ifstream cin ("zeap.in");
ofstream cout ("zeap.out");

#define inf 1000000000

struct Nod{
    
    Nod *left, *right;
    int key,priority;
    
    Nod(int k,int p) { key = k, priority = p; left = right = NULL; Max = Min = k; MinDif = inf; MaxDif = 0;}
    
    ///
    
    int Max,Min;
    int MinDif;
    int MaxDif;
};

void Update ( Nod * root)
{
    if(root == NULL)
        return;
    
    root-> Min = root->key;
    root-> Max = root->key;
    
    root-> MinDif = inf;
    root-> MaxDif = 0;
    
    if(root->left != NULL)
    {
        root-> Min = min(root-> Min, root -> left -> Min);
        root-> Max = max(root-> Max, root -> left -> Max);
        
        root->MinDif = min(root->key - root -> left -> Max, root->left->MinDif);
        
        root->MaxDif = root->key - root -> left -> Min;
    }
    if(root->right != NULL)
    {
        root-> Min = min(root-> Min, root -> right -> Min);
        root-> Max = max(root-> Max, root -> right -> Max);
        
        root->MinDif = min(root->MinDif, root->right->Min - root -> key);
        root->MinDif = min(root->MinDif, root->right->MinDif);
        
        root->MaxDif = root->right->Max - root -> key;
        if(root->left != NULL)
            root-> MaxDif = root->right->Max - root->left->Min;
    }
    
}

void Split(Nod * root, int key, Nod *& left, Nod *& right)
{
    left = right = root;
    
    if(root == NULL)
        return;
    
    if(root -> key > key)
        Split(root -> left, key, left, root -> left);
    else
        Split(root -> right, key, root -> right, right);
    Update(root);
}

void Merge(Nod *& root, Nod * left, Nod * right)
{
    if(left == NULL || right == NULL)
    {
        root = left == NULL ? right : left;
        return;
    }
    
    if(left -> priority > right -> priority)
    {
        root = left;
        Merge(root -> right, root -> right, right);
    }
    else
    {
        root = right;
        Merge(root -> left, left, root -> left);
    }
    Update(root);
}

bool Check(Nod *&root, int key)
{
    if(root == NULL)
        return 0;
    Nod * left = NULL, * right = NULL, * tmp = NULL;
    Split(root, key, left, right);
    Split(left, key-1, left, tmp);
    Merge(root, left, tmp);
    Merge(root, root, right);
    
    if(tmp == NULL)
        return 0;
    return 1;
    
}

void Insert(Nod *&root, int key, int priority)
{
    if(Check(root, key))
        return;
    
    Nod * left = NULL, * right = NULL;
    
    Split(root,key,left,right);
    Merge(root, left, new Nod(key,priority));
    Merge(root, root, right);
}

void Erase(Nod *&root, int key)
{
    if(!Check(root, key))
    {
        cout<<-1<<'\n';
        return ;
    }
    Nod * left = NULL, * right = NULL, * tmp = NULL;
    Split(root, key, left, right);
    Split(left, key - 1, left, tmp);
    delete tmp;
    Merge(root, left, right);
}

int main()
{
    srand(time(NULL));
    
    Nod * root = NULL;
    char ch;
    int value;
    
    while(cin>>ch)
    {
        if(ch == 'M')
        {
            cin>>ch>>ch;
            if(ch == 'X')
            {
                if(root == NULL || root->MaxDif == 0)
                    cout<<-1<<'\n';
                else
                    cout<<root->MaxDif<<'\n';
            }
            else
            {
                if(root == NULL || root->MinDif == inf)
                    cout<<-1<<'\n';
                else
                    cout<<root->MinDif<<'\n';
            }
            continue;
        }
        
        cin>>value;
        if(ch == 'I')
            Insert(root, value, rand());
        if(ch == 'S')
            Erase(root, value);
        if(ch == 'C')
            cout<<Check(root, value)<<'\n';
        
    }
    
    return 0;
}


/*
 
I 3
I 4
I 2
C 4
Max
Min
C 2
 
 */