Cod sursa(job #947736)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 8 mai 2013 12:22:14
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 4.63 kb
#include <cstdlib>
#include <ctime>

#include <fstream>
#include <algorithm>

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();
    }

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

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

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

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

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

    void Erase(int lower, int upper) {
        PairNode roots = Split(treapRoot, lower - 1);
        roots.right = Split(roots.right, upper).right;
        treapRoot = Merge(roots.left, roots.right);
    }

    int Search(int value) {
        return Search(treapRoot, value);
    }

    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 newRoots = Split(treapRoot, key);
        left.treapRoot = newRoots.left;
        right.treapRoot = newRoots.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 = partialSplit.right;
            root->Update();
            return PairNode(partialSplit.left, root);
        } else {
            PairNode partialSplit = Split(root->right, key);
            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);
            return new Node(key, priority, newRoots.left, newRoots.right);
        }
        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 (key == root->key) {
            Node *newRoot = Merge(root->left, root->right);
            delete root;
            return root = newRoot;
        }
        if (key < root->key)
            root->left = Erase(root->left, key);
        else
            root->right = Erase(root->right, key);
        root->Update();
        return root;
    }

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

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

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