Cod sursa(job #1276210)

Utilizator ChallengeMurtaza Alexandru Challenge Data 26 noiembrie 2014 01:24:03
Problema Sortare prin comparare Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 9.34 kb

#include <fstream>
#include <algorithm>

using namespace std;

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

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

template<class T> class AVL;

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

    T 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()
    {
        balance=0;
        if(left && right)
        {
            balance=left->height-right->height;
        }
        else if(left)
        {
            balance=left->height+1;
        }
        else if(right)
        {
            balance=-(right->height+1);
        }
    }

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

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

    friend class AVL<T>;
};

template<class T>
class AVL
{
public:
    class Iterator
    {
    public:
        T& operator* ()
        {
            return node->value;
        }

        Iterator& operator++ ()
        {
            Next();
            return *this;
        }

        bool operator!= (const Iterator &obj)
        {
            return this->node!=obj.node || this->count!=obj.count;
        }

    private:
        Iterator(AVL<T> *avl, AVLNode<T> *node, int count=1):avl(avl),node(node),count(count){}

        void Next()
        {
            ++count;
            if(count>node->count)
            {
                avl->param2=node->value;
                node=avl->Next(avl->root);
                count=1;
            }
        }

        AVL<T> *avl;
        AVLNode<T> *node;
        int count;

        friend class AVL<T>;
    };

    AVL()
        : root(NULL),sentinel(this,NULL)
    {
    }
    ~AVL()
    {
        if(root)
        {
            Delete(root);
        }
    }

    Iterator Begin()
    {
        return Iterator(this,Min(root));
    }

    Iterator End()
    {
        return Iterator(this,Max(root));
    }

    Iterator Sentinel()
    {
        return sentinel;
    }

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

    Iterator Find(T value)
    {
        param1=value;

        AVLNode<T> *node = Find(root);
        if(node)
        {
            return Iterator(this,node);
        }
        return sentinel;
    }

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

        root=Insert(root);
    }

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

            root=Erase(root);
        }
    }

    Iterator NthElement(int pos)
    {
        if(pos<1 || pos>root->weight)
        {
            return sentinel;
        }
        param2 = pos;
        AVLNode<T> *node = NthElement(root);
        return Iterator(this,node,param2);
    }

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

    AVLNode<T>* Min(AVLNode<T> *node)
    {
        if(!node)
        {
            return NULL;
        }
        if(node->left)
        {
            return Min(node->left);
        }
        return node;
    }

    AVLNode<T>* Max(AVLNode<T> *node)
    {
        if(!node)
        {
            return NULL;
        }
        if(node->right)
        {
            return Max(node->right);
        }
        return node;
    }

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

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

    AVLNode<T>* Find(AVLNode<T> *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<T>* Insert(AVLNode<T> *node)
    {
        if(!node)
        {
            return new AVLNode<T>(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<T>* RotateLeft(AVLNode<T> *node)
    {
        AVLNode<T> *temp=node->right;
        node->right=temp->left;
        temp->left=node;

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

        return temp;
    }

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

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

        return temp;
    }

    AVLNode<T>* Balance(AVLNode<T> *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<T>* Erase(AVLNode<T> *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<T> *temp=node->right;
                    delete node;
                    node=temp;
                }
                else if(!node->right)
                {
                    AVLNode<T> *temp=node->left;
                    delete node;
                    node=temp;
                }
                else
                {
                    AVLNode<T> *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;
    }

    AVLNode<T>* NthElement(AVLNode<T> *root)
    {
        if(root->left)
        {
            if(root->left->weight>=param2)
            {
                return NthElement(root->left);
            }
            param2-=root->left->weight;
        }
        if(root->count>=param2)
        {
            return root;
        }
        if(root->right)
        {
            param2-=root->count;
            return NthElement(root->right);
        }
        return NULL;
    }

    AVLNode<T> *root;
    Iterator sentinel;

    //internal use, no actual data stored here
    T param1;
    int param2;

    friend class Iterator;
};

int N,x;
AVL<int> S;

int main()
{
    fin>>N;
    for(int i=1;i<=N;++i)
    {
        fin>>x;
        S.Insert(x);
    }
    fin.close();

    for(int i=1;i<=N;++i)
    {
        fout<<*S.NthElement(i)<<" ";
    }

    /*
    for(AVL<int>::Iterator it=S.Begin();it!=S.Sentinel();++it)
    {
        fout<<*it<<" ";
    }
    */
    fout.close();
    return 0;
}