Cod sursa(job #1198698)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 16 iunie 2014 18:38:14
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.45 kb
#include <cstdlib>
#include <ctime>

#include <fstream>
#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) {
        pair<Node*, Node*> newRoots = Split(treapRoot, key - 1);
        newRoots.second = Split(newRoots.second, key).second;
        treapRoot = Merge(newRoots.first, newRoots.second);
    }

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

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

        Node(const int _key = 0, 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(0, -1, NULL, NULL);
            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) {
            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 where) {
        if (root == NIL)
            return make_pair(NIL, NIL);
        if (where < root->key) {
            pair<Node*, Node*> partialSplit = Split(root->left, where);
            root->left = partialSplit.second;
            root->Update();
            return make_pair(partialSplit.first, root);
        } else {
            pair<Node*, Node*> partialSplit = Split(root->right, where);
            root->right = partialSplit.first;
            root->Update();
            return make_pair(root, partialSplit.second);
        }
    }

    bool Find(Node *root, const int key) const {
        if (root == NIL)
            return false;
        if (key == root->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");
    Treap T = Treap();
    int q;
    cin >> q;
    for (; q > 0; --q) {
        int type, value;
        cin >> type >> value;
        if (type == 1) {
            if (!T.Find(value))
                T.Insert(value);
        } else if (type == 2) {
            if (T.Find(value))
                T.Erase(value);
        } else if (type == 3) {
            cout << int(T.Find(value)) << "\n";
        }
    }
    cin.close();
    cout.close();
    return 0;
}