Cod sursa(job #1231474)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 20 septembrie 2014 19:20:19
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 6.14 kb
#include <bits/stdc++.h>

using namespace std;

template <typename T>
class SplayTree
{
public:

    SplayTree();
    SplayTree(vector<T> &v);

    bool insert(const T& value);
    bool find(const T& value);
    bool erase(const T& value);

    void inorder();

protected:

    class Node
    {
    public:

        T key;
        Node *left, *right;

        Node(const T& value);
        Node(const T value, Node *_left, Node *_right);

        void update();
    };

    Node *root;

    Node* rotateLeft(Node *root);
    Node* rotateRight(Node *root);

    Node* splay(Node *root, const T& value);

    bool insert(Node *&root, const T& value);
    bool find(Node *&root, const T& value);
    bool erase(Node *&root, const T& value);

    void inorder(Node *root);
};

///--------------------------------------------------------------------------------------
/// begin class Node implementation

template <typename T>
SplayTree<T>::Node::Node(const T& value)
{
    this->key = value;
    this->left = nullptr;
    this->right = nullptr;
}

template <typename T>
SplayTree<T>::Node::Node(const T value, Node *_left, Node *_right)
{
    this->key = value;
    this->left = _left;
    this->right = _right;
}

template <typename T>
void SplayTree<T>::Node::update()
{
}

template <typename T>
typename SplayTree<T>::Node* SplayTree<T>::rotateRight(Node *N)
{
    if ( N != nullptr )
    {
        Node *aux = N->left;
        N->left = aux->right;
        aux->right = N;

        aux->update();
        N->update();

        return aux;
    }
}

template <typename T>
typename SplayTree<T>::Node* SplayTree<T>::rotateLeft(Node *N)
{
    if ( N != nullptr )
    {
        Node *aux = N->right;
        N->right = aux->left;
        aux->left = N;

        aux->update();
        N->update();

        return aux;
    }
}

/// end class Node implementation
///--------------------------------------------------------------------------------------

template <typename T>
SplayTree<T>::SplayTree()
{
    this->root = nullptr;
    srand( time(0) );
}

template <typename T>
typename SplayTree<T>::Node* SplayTree<T>::splay(Node *root, const T& value)
{
    if ( root == nullptr || root->key == value )
        return root;

    if ( value < root->key )
    {
        if ( root->left == nullptr )
            return root;

        if ( value < root->left->key ) /// Zig-Zig (left left)
        {
            root->left->left = splay(root->left->left, value);
            root = rotateRight(root);
        }
        else
        if ( value > root->left->key ) /// Zig-Zag (left right)
        {
            root->left->right = splay(root->left->right, value);

            if ( root->left->right != nullptr )
                root->left = rotateLeft(root->left);
        }

        if ( root->left == nullptr )
            return root;
        else
            return rotateRight(root);
    }
    else
    {
        if ( root->right == nullptr )
            return root;

        if ( value < root->right->key ) /// Zig-Zag (right left)
        {
            root->right->left = splay(root->right->left, value);

                if ( root->right->left != nullptr )
                root->right = rotateRight(root->right);
        }
        else
        if ( value > root->right->key ) /// Zag-Zag (right, right)
        {
            root->right->right = splay(root->right->right, value);
            root = rotateLeft(root);
        }

        if ( root->right == nullptr )
            return root;
        else
            return rotateLeft(root);
    }
}

template <typename T>
bool SplayTree<T>::insert(const T& value)
{
    return insert(root, value);
}

template <typename T>
bool SplayTree<T>::insert(Node *&root, const T& value)
{
    if ( root == nullptr )
    {
        root = new Node(value);
        return true;
    }

    root = splay(root, value);

    if ( root->key == value )
        return false;

    Node *newNode = new Node(value);

    if ( value < root->key )
    {
        newNode->right = root;
        newNode->left = root->left;
        root->left = nullptr;

        root = newNode;
    }
    else
    {
        newNode->left = root;
        newNode->right = root->right;
        root->right = nullptr;

        root = newNode;
    }

    return true;
}

template <typename T>
bool SplayTree<T>::find(const T& value)
{
    return find(root, value);
}

template <typename T>
bool SplayTree<T>::find(Node *&root, const T& value)
{
    root = splay(root, value);

    return ( root->key == value );
}

template <typename T>
bool SplayTree<T>::erase(const T& value)
{
    return erase(root, value);
}

template <typename T>
bool SplayTree<T>::erase(Node *&root, const T& value)
{
    if ( root == nullptr )
        return false;

    root = splay(root, value);

    if ( root->key != value )
        return false;

    Node *L = root->left;
    Node *R = root->right;

    delete root;
    root = nullptr;

    if ( L == nullptr )
        root = R;
    else
    {
        Node *maxim, *father;
        Node *auxL = L;
        Node *v[2];
        int tip = 0;
        v[0] = v[1] = nullptr;

        while ( auxL != nullptr )
        {
            v[tip] = auxL;
            auxL = auxL->right;
            tip ^= 1;
        }

        father = v[tip];
        maxim = v[tip ^ 1];

        if ( father != nullptr )
            father->right = nullptr;

        assert( maxim != nullptr );

        if ( maxim != L ) maxim->left = L;
        maxim->right = R;

        root = maxim;
    }

    return true;
}

template <typename T>
void SplayTree<T>::inorder(Node *root)
{
    if ( root == nullptr )
        return;

    inorder(root->left);
    cout << root->key << " ";
    inorder(root->right);
}

template <typename T>
void SplayTree<T>::inorder()
{
    return inorder(root);
}

int main()
{
    ifstream in("hashuri.in");
    ofstream out("hashuri.out");

    in.sync_with_stdio( false );

    int N, type, key;

    in >> N;

    SplayTree <int> T;

    for ( int k = 0; k < N; ++k )
    {
        in >> type >> key;

        if ( type == 1 )
        {
            T.insert(key);
        }

        if ( type == 2 )
        {
           T.erase(key);
        }

        if ( type == 3 )
        {
            out << T.find(key) << "\n";
        }
    }

    return 0;
}