Cod sursa(job #944653)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 29 aprilie 2013 11:22:23
Problema Hashuri Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 4.38 kb
#include <cstdlib>
#include <ctime>

#include <fstream>

using namespace std;

class Node {
  public:
    int key, priority, size;
    Node *left, *right;

    Node(int key, int priority, Node *left, Node *right) {
        this->key = key;
        this->priority = priority;
        this->left = left; this->right = right;
        this->Update();
    }

    void Update() {
        size = 1;
        if (left != NULL)
            size += left->size;
        if (right != NULL)
            size += right->size;
    }

    static Node *BuildSentinel() {
        Node *sentinel = new Node(0, -1, NULL, NULL);
        sentinel->size = 0;
        sentinel->left = sentinel->right = sentinel;
        return sentinel;
    }
};

class Treap {
  public:
    Treap() {
        treapRoot = NIL;
    }

    void Insert(int key) {
        treapRoot = Insert(treapRoot, key, rand());
    }

    void Erase(int key) {
        treapRoot = Erase(treapRoot, key);
    }

    bool Search(int key) {
        return Search(treapRoot, key);
    }

    static Treap Merge(Treap &left, Treap &right) {
        Treap newTreap;
        newTreap.treapRoot = newTreap.Merge(left.treapRoot, right.treapRoot);
        return newTreap;
    }

    void Split(int key, Treap &left, Treap &right) {
        PairNode treaps = Split(treapRoot, key);
        left.treapRoot = treaps.left;
        right.treapRoot = treaps.right;
    }

  private:
    class PairNode {
      public:
        Node *left, *right;

        PairNode(Node *left, Node *right) {
            this->left = left; this->right = right;
        }
    };

    static Node *NIL;

    Node *treapRoot;

    Node *Merge(Node *left, Node *right) {
        if (left == NIL && right == NIL)
            return NIL;
        if (left->priority < right->priority) {
            right->left = Merge(left, right->left);
            right->Update();
            return right;
        } else {
            left->right = Merge(left->right, right);
            left->Update();
            return left;
        }
    }

    PairNode Split(Node *root, int key) {
        if (root == NIL)
            return PairNode(NIL, NIL);
        if (key < root->key) {
            PairNode partialSplit = Split(root->left, key);
            root->left = Merge(partialSplit.right, root->left);
            root->Update();
            return PairNode(partialSplit.left, root);
        } else {
            PairNode partialSplit = Split(root->right, key);
            root->right = Merge(root->right, partialSplit.left);
            root->Update();
            return PairNode(root, partialSplit.right);
        }
    }

    Node *Insert(Node *root, int key, int priority) {
        if (root->priority < priority) {
            PairNode newRoots = Split(root, key);
            root = new Node(key, priority, newRoots.left, newRoots.right);
            return root;
        }
        if (key <= root->key)
            root->left = Insert(root->left, key, priority);
        else
            root->right = Insert(root->right, key, priority);
        root->Update();
        return root;
    }

    Node *Erase(Node *root, int key) {
        if (root == NIL)
            return NIL;
        if (root->key == key) {
            Node *newRoot = Merge(root->left, root->right);
            delete root;
            return newRoot;
        }
        if (key < root->key)
            root->left = Erase(root->left, key);
        else
            root->right = Erase(root->right, key);
        root->Update();
        return root;
    }

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

Node *Treap::NIL = Node::BuildSentinel();

int main() {
    srand(time(NULL));
    Treap T;
    ifstream in("hashuri.in");
    ofstream out("hashuri.out");
    int Q; in >> Q;
    for (; Q > 0; --Q) {
        int type, value; in >> type >> value;
        if (type == 1 && !T.Search(value))
            T.Insert(value);
        if (type == 2)
            T.Erase(value);
        if (type == 3)
            out << T.Search(value) << "\n";
    }
    in.close();
    out.close();
    return 0;
}