Cod sursa(job #1165372)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 2 aprilie 2014 17:31:58
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.74 kb
#include <cstdlib>
#include <ctime>

#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

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

    void Insert(const int key) {
        pair<Node*, Node*> newRoots = Split(treapRoot, key);
        treapRoot = Merge(Merge(newRoots.first, new Node(key, rand(), NIL, NIL)), newRoots.second);
    }

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

    bool Find(const int key) {
        return Find(treapRoot, key);
    }

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

        Node(const int _key = -1, const int _priority = -1, Node *_left = NULL, Node *_right = NULL):
          key(_key),
          priority(_priority),
          size(1),
          left(_left),
          right(_right) {
            Update();
        }

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

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

    static Node *NIL;

    Node *treapRoot;

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

    pair<Node*, Node*> Split(Node *root, const int key) {
        if (root == NIL)
            return make_pair(NIL, NIL);
        if (key <= root->key) {
            pair<Node*, Node*> partialSplit = Split(root->left, key);
            root->left = partialSplit.second;
            root->Update();
            return make_pair(partialSplit.first, root);
        } else {
            pair<Node*, Node*> partialSplit = Split(root->right, key);
            root->right = partialSplit.first;
            root->Update();
            return make_pair(root, partialSplit.second);
        }
    }

    Node *Erase(Node *root, const int key) {
        if (root == NIL)
            return NIL;
        if (root->key == 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;
    }

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

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

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