Cod sursa(job #944520)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 28 aprilie 2013 22:42:39
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 5.37 kb
#include <cstdio>
#include <cassert>

#include <algorithm>

using namespace std;

typedef long long int64;

class Reader {
  public:
    Reader(FILE *stream, const int size = (1 << 16)):
            size(size),
            pointer(0),
            stream(stream) {
        buffer = new char[size];
        assert(fread(buffer, 1, size, this->stream) != 0);
    }

    template<class IntType>
    IntType NextInt() {
        IntType value = 0;
        bool negative = false;
        while ((Current() < '0' || Current() > '9') && Current() != '-')
            NextPosition();
        if (Current() == '-') {
            negative = true;
            NextPosition();
        }
        while(Current() >= '0' && Current() <= '9') {
            value = value * 10 + Current() - '0';
            NextPosition();
        }
        if (negative)
            value = -value;
        return value;
    }

    Reader &operator>>(int &value) {
        value = NextInt<int>();
        return *this;
    }

    Reader &operator>>(long long &value) {
        value = NextInt<long long>();
        return *this;
    }

  private:
    int size;
    int pointer;
    char *buffer;
    FILE *stream;

    char Current() const {
        return buffer[pointer];
    }

    void NextPosition() {
        if(++pointer == size) {
            assert(fread(buffer, 1, size, stream) != 0);
            pointer = 0;
        }
    }
};

class Node {
  public:
    int key;
    int level;
    Node *left;
    Node *right;

    Node(const int key, const int level, Node* left, Node* right):
            key(key),
            level(level),
            left(left),
            right(right) {
    }
};

class AATree {
  public:
    static void BuildSentinel() {
        NIL->left = NIL;
        NIL->right = NIL;
    }

    AATree() {
        root = NIL;
    }

    void Insert(const int key) {
        Insert(root, key);
    }

    void Delete(const int key) {
        Delete(root, key);
    }

    bool Search(const int key) {
        return Search(root, key);
    }

  private:
    static Node *NIL;

    Node *root;

    void Skew(Node* &node) {
        if (node == NIL || node->left == NIL)
            return;
        if (node->left->level == node->level) {
            Node *aux = node->left;
            node->left = aux->right;
            aux->right = node;
            node = aux;
        }
    }

    void Split(Node* &node) {
        if (node == NIL || node->right == NIL || node->right->right == NIL)
            return;
        if (node->level == node->right->right->level) {
            Node *aux = node->right;
            node->right = aux->left;
            aux->left = node;
            ++aux->level;
            node = aux;
        }
    }

    void DecreaseLevel(Node* &node) {
        int reqLevel = min(node->left->level, node->right->level) + 1;
        if (reqLevel < node->level) {
            node->level = reqLevel;
            if (reqLevel < node->right->level)
                node->right->level = reqLevel;
        }
    }

    int Successor(Node *node) {
        node = node->right;
        for (; node->left != NIL; node = node->left);
        return node->key;
    }

    int Predecessor(Node *node) {
        node = node->left;
        for (; node->right != NIL; node = node->right);
        return node->key;
    }

    void Insert(Node* &node, const int key) {
        if (node == NIL) {
            node = new Node(key, 1, NIL, NIL);
            return;
        }
        if (key <= node->key)
            Insert(node->left, key);
        else
            Insert(node->right, key);
        Skew(node);
        Split(node);
    }

    void Delete(Node* &node, const int key) {
        if (node == NIL)
            return;
        if (key < node->key)
            Delete(node->left, key);
        if (key > node->key)
            Delete(node->right, key);
        if (key == node->key) {
            if (node->left == NIL && node->right == NIL) {
                delete node;
                node = NIL;
            } else if (node->left == NIL) {
                int newKey = Successor(node);
                Delete(node->right, newKey);
                node->key = newKey;
            } else {
                int newKey = Predecessor(node);
                Delete(node->left, newKey);
                node->key = newKey;
            }
        }
        DecreaseLevel(node);
        Skew(node);
        Skew(node->right);
        Split(node);
        Split(node->right);
    }

    bool Search(Node* &node, const int key) {
        if (node == NIL)
            return false;
        if (node->key == key)
            return true;
        if (key < node->key)
            return Search(node->left, key);
        else
            return Search(node->right, key);
    }
};

Node *AATree::NIL = new Node(0, 0, NULL, NULL);

int main() {
    AATree::BuildSentinel();
    assert(freopen("hashuri.in", "r", stdin));
    assert(freopen("hashuri.out", "w", stdout));
    Reader in = Reader(stdin);
    int Q; in >> Q;
    AATree tree = AATree();
    for (; Q > 0; --Q) {
        int type, value; in >> type >> value;
        if (type == 1 && !tree.Search(value))
            tree.Insert(value);
        if (type == 2)
            tree.Delete(value);
        if (type == 3)
            printf("%d\n", tree.Search(value));
    }
    return 0;
}