Cod sursa(job #944521)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 28 aprilie 2013 22:44:10
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 4.01 kb
#include <fstream>
#include <algorithm>

using namespace std;

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();
    ifstream in("hashuri.in");
    ofstream out("hashuri.out");
    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)
            out << tree.Search(value) << "\n";
    }
    in.close();
    out.close();
    return 0;
}