Cod sursa(job #1275379)

Utilizator ChallengeMurtaza Alexandru Challenge Data 25 noiembrie 2014 02:34:08
Problema Zeap Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 8.96 kb
#include <fstream>
#include <algorithm>

using namespace std;

const char InFile[]="zeap.in";
const char OutFile[]="zeap.out";

ifstream fin(InFile);
ofstream fout(OutFile);

class AVL;

class AVLNode
{
public:
    AVLNode(int value=0, int count=1):value(value),count(count),height(0),weight(1),balance(0),left(NULL),right(NULL){}

    int value;

private:
    void UpdateHeight()
    {
        height=0;
        if(left && right)
        {
            height=max(left->height,right->height)+1;
        }
        else if(left)
        {
            height=left->height+1;
        }
        else if(right)
        {
            height=right->height+1;
        }
    }

    void UpdateWeight()
    {
        weight=count;
        if(left)
        {
            weight+=left->weight;
        }
        if(right)
        {
            weight+=right->weight;
        }
    }

    void UpdateBalance()
    {
        height=0;
        if(left && right)
        {
            height=left->height-right->height;
        }
        else if(left)
        {
            height=left->height+1;
        }
        else if(right)
        {
            height=-(right->height+1);
        }
    }

    void Update()
    {
        UpdateHeight();
        UpdateWeight();
        UpdateBalance();
    }

    int count,height,weight,balance;
    AVLNode *left,*right;

    friend class AVL;
};

class AVL
{
public:
    AVL(int defaultValue=0):defaultValue(defaultValue){}
    ~AVL()
    {
        if(root)
        {
            Delete(root);
        }
    }

    int Size()
    {
        if(root)
        {
            return root->weight;
        }
        return 0;
    }

    int Min()
    {
        AVLNode *node=NULL;
        if(root)
        {
            node=Min(root);
        }
        if(node)
        {
            return node->value;
        }
        return defaultValue;
    }

    int Max()
    {
        AVLNode *node=NULL;
        if(root)
        {
            node=Max(root);
        }
        if(node)
        {
            return node->value;
        }
        return defaultValue;
    }

    int Next(int value)
    {
        param1=value;
        AVLNode *temp=Next(root);
        if(!temp)
        {
            return defaultValue;
        }
        return temp->value;
    }

    int Prev(int value)
    {
        param1=value;
        AVLNode *temp=Prev(root);
        if(!temp)
        {
            return defaultValue;
        }
        return temp->value;
    }

    int Find(int value)
    {
        param1=value;

        AVLNode *node = Find(root);
        if(node)
        {
            return node->count;
        }
        return 0;
    }

    void Insert(int value, int cnt=1)
    {
        if(!root)
        {
            root=new AVLNode(value,cnt);
            return;
        }
        param1=value;
        param2=cnt;

        root=Insert(root);
    }

    void Erase(int value, int cnt=1)
    {
        if(root)
        {
            param1=value;
            param2=cnt;

            root=Erase(root);
        }
    }

private:
    void Delete(AVLNode *node)
    {
        if(node->left)
        {
            Delete(node->left);
        }
        if(node->right)
        {
            Delete(node->right);
        }
        delete node;
    }

    AVLNode* Min(AVLNode *node)
    {
        if(node->left)
        {
            return Min(node->left);
        }
        return node;
    }

    AVLNode* Max(AVLNode *node)
    {
        if(node->right)
        {
            return Max(node->right);
        }
        return node;
    }

    AVLNode* Next(AVLNode *node)
    {
        if(!node)
        {
            return NULL;
        }
        if(param1<node->value)
        {
            AVLNode *temp=Next(node->left);
            if(!temp)
            {
                return node;
            }
            return temp;
        }
        else
        {
            return Next(node->right);
        }
    }

    AVLNode* Prev(AVLNode *node)
    {
        if(!node)
        {
            return NULL;
        }
        if(node->value<param1)
        {
            AVLNode *temp=Prev(node->right);
            if(!temp)
            {
                return node;
            }
            return temp;
        }
        else
        {
            return Prev(node->left);
        }
    }

    AVLNode* Find(AVLNode *node)
    {
        if(!node)
        {
            return NULL;
        }
        if(param1<node->value)
        {
            return Find(node->left);
        }
        else if(node->value<param1)
        {
            return Find(node->right);
        }
        return node;
    }

    AVLNode* Insert(AVLNode *node)
    {
        if(!node)
        {
            return new AVLNode(param1,param2);
        }
        if(param1<node->value)
        {
            node->left = Insert(node->left);
        }
        else if(node->value<param1)
        {
            node->right = Insert(node->right);
        }
        else
        {
            node->count+=param2;
        }

        node = Balance(node);
        return node;
    }

    AVLNode* RotateLeft(AVLNode *node)
    {
        AVLNode *temp=node->right;
        node->right=temp->left;
        temp->left=node;

        node->Update();
        temp->Update();

        return temp;
    }

    AVLNode* RotateRight(AVLNode *node)
    {
        AVLNode *temp=node->left;
        node->left=temp->right;
        temp->right=node;

        node->Update();
        temp->Update();

        return temp;
    }

    AVLNode* Balance(AVLNode *node)
    {
        node->Update();
        if(node->balance==2)
        {
            if(node->left->balance<0)
            {
                node->left=RotateLeft(node->left);
            }
            node=RotateRight(node);
        }
        else if(node->balance==-2)
        {
            if(node->right->balance>0)
            {
                node->right=RotateRight(node->right);
            }
            node=RotateLeft(node);
        }

        return node;
    }

    AVLNode* Erase(AVLNode *node)
    {
        if(!node)
        {
            return NULL;
        }
        if(param1<node->value)
        {
            node->left=Erase(node->left);
        }
        else if(node->value<param1)
        {
            node->right=Erase(node->right);
        }
        else
        {
            node->count-=param2;

            if(node->count<=0)
            {
                if(!node->left && !node->right)
                {
                    delete node;
                    return NULL;
                }
                else if(!node->left)
                {
                    AVLNode *temp=node->right;
                    delete node;
                    return temp;
                }
                else if(!node->right)
                {
                    AVLNode *temp=node->left;
                    delete node;
                    return temp;
                }
                else
                {
                    AVLNode *temp=Max(node->left);
                    node->value=temp->value;
                    node->count=temp->count;

                    param1=temp->value;
                    temp->count=0;

                    node->left=Erase(node->left);
                }
            }
        }

        node=Balance(node);
        return node;
    }

    int defaultValue;
    AVLNode *root;

    int param1,param2;
};

int x;
char op[8];

AVL S,D;

int main()
{
    while(fin)
    {
        fin>>op;
        if(op[0]=='I')
        {
            fin>>x;
            if(S.Find(x))
            {
                continue;
            }
            S.Insert(x);
            int n=S.Next(x);
            int p=S.Prev(x);
            if(n)
            {
                D.Insert(n-x);
            }
            if(p)
            {
                D.Insert(x-p);
            }
            if(n && p)
            {
                D.Erase(n-p);
            }
        }
        else if(op[0]=='S')
        {
            fin>>x;
            if(!S.Find(x))
            {
                fout<<"-1\n";
                continue;
            }

            int n=S.Next(x);
            int p=S.Prev(x);
            if(n)
            {
                D.Erase(n-x);
            }
            if(p)
            {
                D.Erase(x-p);
            }
            if(n && p)
            {
                D.Insert(n-p);
            }
            S.Erase(x);
        }
        else if(op[0]=='C')
        {
            fin>>x;
            if(S.Find(x))
            {
                fout<<"1\n";
            }
            else
            {
                fout<<"0\n";
            }
        }
        else if(op[1]=='A')
        {
            if(S.Size()<2)
            {
                fout<<"-1\n";
            }
            else
            {
                fout<<S.Max()-S.Min()<<"\n";
            }
        }
        else if(op[1]=='I')
        {
            if(S.Size()<2)
            {
                fout<<"-1\n";
            }
            else
            {
                fout<<D.Min()<<"\n";
            }
        }
    }
    fin.close();
    fout.close();
    return 0;
}