Cod sursa(job #1754972)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 9 septembrie 2016 01:47:27
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 4.13 kb
#include <bits/stdc++.h>

using namespace std;

template<class T>
class Treap {
    public:
        Treap() {
            root_ = nullptr;
        }

        bool Find(T value) {
            return FindValue(root_, value);
        }

        void Insert(T value) {
            if (Find(value)) {
                return;
            }
            root_ = InsertValue(value);
        }

        void Remove(T value) {
            root_ = RemoveValue(root_, value);
        }

    private:
        struct Node {
            Node* left_;
            Node* right_;
            T value_;
            int priority_;
            int subtree_;

            Node(int value) : value_(value) {
                left_ = nullptr;
                right_ = nullptr;
                priority_ = (rand() << 16) ^ rand();
                subtree_ = 1;
            }
        };

        int GetSubtreeSize(Node* node) {
            return node == nullptr ? 0 : node->subtree_;
        }

        void UpdateNode(Node* node) {
            if (node == nullptr) {
                return;
            }
            node->subtree_ = 1 + GetSubtreeSize(node->left_) + GetSubtreeSize(node->right_);
        }

        pair<Node*, Node*> Split(Node* current_node, T split_value) {
            if (current_node == nullptr) {
                return {nullptr, nullptr};
            }

            pair<Node*, Node*> roots;
            if (current_node->value_ <= split_value) {
                roots = Split(current_node->right_, split_value);
                current_node->right_ = roots.first;
                UpdateNode(current_node->right_);
                roots.first = current_node;
            } else {
                roots = Split(current_node->left_, split_value);
                current_node->left_ = roots.second;
                UpdateNode(current_node->left_);
                roots.second = current_node;
            }

            return roots;
        }

        Node* Merge(Node* left_root, Node* right_root) {
            if (left_root == nullptr) {
                return right_root;
            }

            if (right_root == nullptr) {
                return left_root;
            }

            if (left_root->priority_ > right_root->priority_) {
                left_root->right_ = Merge(left_root->right_, right_root);
                UpdateNode(left_root);
                return left_root;
            } else {
                right_root->left_ = Merge(left_root, right_root->left_);
                UpdateNode(right_root);
                return right_root;
            }
        }

        bool FindValue(Node* node, T value) {
            if (node == nullptr) {
                return false;
            }

            if (value < node->value_) {
                return FindValue(node->left_, value);
            } else if (value > node->value_) {
                return FindValue(node->right_, value);
            }

            return true;
        }

        Node* InsertValue(T value) {
            pair<Node*, Node*> roots = Split(root_, value);
            return Merge(Merge(roots.first, new Node(value)), roots.second);
        }

        Node* RemoveValue(Node* node, T value) {
            if (node == nullptr) {
                return nullptr;
            }

            if (value == node->value_) {
                Node* old_node = node;
                node = Merge(node->left_, node->right_);
                delete old_node;
            } else if (value < node->value_) {
                node->left_ = RemoveValue(node->left_, value);
            } else {
                node->right_ = RemoveValue(node->right_, value);
            }

            return node;
        }

        Node* root_;
};

int main() {
    srand(time(0));

    ifstream cin("hashuri.in");
    ofstream cout("hashuri.out");

    Treap<int> treap;

    int t;
    cin >> t;
    for (; t; t--) {
        int operation;
        int value;
        cin >> operation >> value;

        switch (operation) {
        case 1:
            treap.Insert(value);
            break;
        case 2:
            treap.Remove(value);
            break;
        default:
            cout << treap.Find(value) << '\n';
        }
    }

    return 0;
}