Cod sursa(job #1268888)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 21 noiembrie 2014 16:58:23
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.42 kb
#include <cstdlib>
#include <ctime>

#include <fstream>
#include <algorithm>

using namespace std;

class Treap {
  public:
    Treap():
      treapRoot(NULL),
      nil(Node::BuildSentinel()) {
        treapRoot = nil;
    }

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

    void Erase(const int key) {
        pair<Node*, Node*> newRoots = Split(treapRoot, key - 1);
        treapRoot = Merge(newRoots.first, Split(newRoots.second, key).second);
    }

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

  private:
    class Node {
      public:
        static const int NIL_PRIORITY = -1;

        int key, priority, size;
        Node *left, *right;

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

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

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

    Node *treapRoot, *nil;

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

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

    bool Find(Node *root, const int key) const {
        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);
    }
};

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