Cod sursa(job #944525)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 28 aprilie 2013 23:55:19
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.79 kb
#include <cstdlib>
#include <ctime>

#include <fstream>
#include <algorithm>

using namespace std;

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

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

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

class Treap {
  public:
    Treap() {
        nil = new Node(0, -1, NULL, NULL);
        nil->count = 0;
        nil->left = nil->right = nil;
        treapRoot = nil;
    }

    int Size() const {
        return treapRoot->count;
    }

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

  private:
    Node *treapRoot, *nil;

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

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

    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 current = Split(root, key);
            return new Node(key, priority, current.left, current.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 root;
        if (key == root->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 (root->key == key)
            return true;
        if (key < root->key)
            return Search(root->left, key);
        else
            return Search(root->right, key);
    }
};

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