Cod sursa(job #1231511)

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

#define VI vector<int>
#define VII vector<pair<int,int>>
#define QI queue<int>

#define ms(a,v) memset( a, v, sizeof( a ) )
#define FOR(i,a,b) for(int i = a; i <= b; ++i)
#define ROF(i,a,b) for(int i = a; i >= b; i--)
#define foreach(v, c) for( typeof( (c).begin() ) v = (c).begin(); v != (c).end(); ++v)

#define pb push_back
#define pp pair<int,int>
#define mp make_pair
#define fi first
#define se second

#define popcount __builtin_popcount
#define gcd __gcd
#define bit(n,i) ( n & ( 1LL << i ) )
#define lsb(x) ( x & ( -x ) )

#define FIN(str) freopen(str,"r",stdin)
#define FOUT(str) freopen(str,"w",stdout)
#define Fin(str) ifstream(str)
#define Fout(str) ostream(str)
#define SYNC ios_base::sync_with_stdio(0);

#define ll long long
#define ull unsigned long long

inline void read( int &a )
{
    register char ch;
    a = 0;
    int sign = 1;

    do
    {
        ch = getchar();

    } while ( !isdigit( ch ) && ch != '-' );

    if ( ch == '-' )
    {
        sign = -1;
        ch = getchar();
    }

    do
    {
        a = a * 10 + ch - '0';
        ch = getchar();

    } while( isdigit( ch ) );

    a *= sign;
}

inline void write( int a )
{
    char s[20];
    int i = 0;
    int sign = 1;

    if ( a < 0 )
        sign = -1,
        a = -a;

    do
    {
        s[ i++ ] = a % 10 + '0';
        a /= 10;

    } while ( a );

    i--;

    if ( sign == -1 )
        putchar( '-' );

    while ( i >= 0 ) putchar( s[ i-- ] );
}

const int dx[] = { -1, 0, 1, 0 };
const int dy[] = { 0, 1, 0, -1 };

const int dl[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int dc[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

const int INF = 2e9;
const double EPS = 1e-9;

const int Nmax = 1e4 + 2;

const int LgMax = log2(Nmax) + 1;

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:

        Node(){}

        T key;
        Node *left, *right;

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

        void update();
    };

    Node *root, *NIL;

    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)
{
    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)
{
   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()
{
    NIL = new Node(T());
    this->root = NIL;
}

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

    Node *leftTreeMax, *rightTreeMin;
    static Node header;

    header.left = header.right = NIL;
    leftTreeMax = rightTreeMin = &header;

    NIL->key = value;

    while ( true )
    {
        if ( value == root->key ) break;

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

            if ( root->left == NIL ) break;

            rightTreeMin->left = root;
            rightTreeMin = root;
            root = root->left;
        }
        else
        {
            if ( root->right->key < value )
                root = rotateLeft(root);

            if ( root->right == NIL ) break;

            leftTreeMax->right = root;
            leftTreeMax = root;
            root = root->right;
        }
    }

    leftTreeMax->right = root->left;
    rightTreeMin->left = root->right;
    root->left = header.right;
    root->right = header.left;

    return 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 == NIL )
    {
        root = new Node(value);
        root->left = root->right = NIL;
        return true;
    }

    root = splay(root, value);

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

    Node *newNode = new Node(value);

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

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

        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 == NIL )
        return false;

    Node *newNode, *aux = root;

    root = splay(root, value);

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

    if ( root->left == NIL )
        newNode = root->right;
    else
    {
        newNode = splay(root->left, value);
        newNode->right = root->right;
    }

    delete root;
    root = newNode;

    return true;
}

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

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

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

int main()
{
    FIN("hashuri.in");
    FOUT("hashuri.out");

    int N, type, key;

    read( N );

    SplayTree <int> T;

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

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

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

        if ( type == 3 )
        {
           printf("%d\n", T.find(key));
        }
    }

    return 0;
}