Cod sursa(job #2260222)

Utilizator BrandonChris Luntraru Brandon Data 14 octombrie 2018 16:50:07
Problema Hashuri Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 7.54 kb
#include <iostream>
#include <fstream>
#include <memory>
#include <random>
#include <cstdlib>

std::ifstream fin("hashuri.in");
std::ofstream fout("hashuri.out");

//using std::shared_ptr;
//using std::make_shared;

const int kInf = 2147483647;

template <typename T>
class TreapNode {
private:
    T value_;
    int key_;
    TreapNode<T> *lf_son_;
    TreapNode<T> *rg_son_;
    TreapNode<T> *parent_;

public:
    TreapNode(TreapNode<T> *parent, T value) {
        parent_ = parent;
        lf_son_ = nullptr;
        rg_son_ = nullptr;

        value_ = value;

        // root needs the smallest possible key
        if (parent_ == nullptr) {
            key_ = 0;
        }
        else {
//            std::random_device rd;
//            std::mt19937 mt(rd());
//            std::uniform_int_distribution<int> generator(1, kInf);
            key_ = rand() % kInf;
        }
    }

    const T &get_value() const {
        return value_;
    }

    const int &get_key() const {
        return key_;
    }

    TreapNode<T> *get_parent_ptr() const {
        return parent_;
    }

    TreapNode<T> *get_lf_son_ptr() const {
        return lf_son_;
    }

    TreapNode<T> *get_rg_son_ptr() const {
        return rg_son_;
    }

    void set_lf_son(TreapNode<T> *son) {
        lf_son_ = son;
    }

    void set_rg_son(TreapNode<T> *son) {
        rg_son_ = son;
    }

    void set_parent(TreapNode<T> *parent) {
        parent_ = parent;
    }
};

template <typename T>
class Treap {
private:
    TreapNode<T> *root_;

    void rotate_left(TreapNode<T> *node_ptr) {
        auto parent = node_ptr->get_parent_ptr();

//        auto lf_son = node_ptr->get_lf_son_ptr();
        auto rg_son = node_ptr->get_rg_son_ptr();
        if (parent->get_lf_son_ptr() == node_ptr) {
            parent->set_lf_son(rg_son);
        }
        else {
            parent->set_rg_son(rg_son);
        }

        if (rg_son != nullptr) {
            rg_son->set_parent(parent);

            node_ptr->set_rg_son(rg_son->get_lf_son_ptr());
            if (rg_son->get_lf_son_ptr() != nullptr) {
                rg_son->get_lf_son_ptr()->set_parent(node_ptr);
            }

            rg_son->set_lf_son(node_ptr);
            node_ptr->set_parent(rg_son);
        }
        else {
            node_ptr->set_rg_son(nullptr);
        }
    }

    void rotate_right(TreapNode<T> *node_ptr) {
        auto parent = node_ptr->get_parent_ptr();

        auto lf_son = node_ptr->get_lf_son_ptr();
//        auto rg_son = node_ptr->get_rg_son_ptr();
        if (parent->get_lf_son_ptr() == node_ptr) {
            parent->set_lf_son(lf_son);
        }
        else {
            parent->set_rg_son(lf_son);
        }

        if (lf_son != nullptr) {
            lf_son->set_parent(parent);

            node_ptr->set_lf_son(lf_son->get_rg_son_ptr());
            if (lf_son->get_rg_son_ptr() != nullptr) {
                lf_son->get_rg_son_ptr()->set_parent(node_ptr);
            }

            lf_son->set_rg_son(node_ptr);
            node_ptr->set_parent(lf_son);
        }
        else {
            node_ptr->set_lf_son(nullptr);
        }
    }

public:
    Treap() {
        root_ = new TreapNode<T>(nullptr, T());
    }

    void insert(const T &val) {
        // Treap is empty
        if (root_->get_lf_son_ptr() == nullptr) {
            root_->set_lf_son(new TreapNode<T>(root_, val));
            return;
        }

        bool made_node = false;
        auto current_node = root_->get_lf_son_ptr();
        while (!made_node) {
            T current_val = current_node->get_value();
            if (current_val == val) {
                return;
            }

            if (val <= current_val && current_node->get_lf_son_ptr() != nullptr) {
                current_node = current_node->get_lf_son_ptr();
            }
            else if (val > current_val && current_node->get_rg_son_ptr() != nullptr) {
                current_node = current_node->get_rg_son_ptr();
            }
            else if (val <= current_val && current_node->get_lf_son_ptr() == nullptr) {
                current_node->set_lf_son(new TreapNode<T>(current_node, val));
                current_node = current_node->get_lf_son_ptr();
                made_node = true;
            }
            else if (val > current_val && current_node->get_rg_son_ptr() == nullptr) {
                current_node->set_rg_son(new TreapNode<T>(current_node, val));
                current_node = current_node->get_rg_son_ptr();
                made_node = true;
            }
        }

        while (current_node->get_key() < current_node->get_parent_ptr()->get_key()) {
            auto parent = current_node->get_parent_ptr();
            if (current_node == parent->get_lf_son_ptr()) {
                rotate_right(parent);
            }
            else {
                rotate_left(parent);
            }

            current_node = parent;
        }
    }

    TreapNode<T> *find(T val) {
        auto current_node = root_->get_lf_son_ptr();
        while (current_node != nullptr && current_node->get_value() != val) {
            if (val <= current_node->get_value()) {
                current_node = current_node->get_lf_son_ptr();
            }
            else {
                current_node = current_node->get_rg_son_ptr();
            }
        }

        return current_node;
    }

    void remove(const T &val) {
        auto current_node = root_->get_lf_son_ptr();
        bool found_val = false;
        while (current_node != nullptr && !found_val) {
            if (val < current_node->get_value()) {
                current_node = current_node->get_lf_son_ptr();
            }
            else if (val > current_node->get_value()){
                current_node = current_node->get_rg_son_ptr();
            }
            else {
                found_val = true;
            }
        }

        if (!found_val) {
            return;
        }

        bool removed = false;
        while (!removed) {
            if (current_node->get_lf_son_ptr() == nullptr && current_node->get_rg_son_ptr() == nullptr) {
                auto parent = current_node->get_parent_ptr();
                if (current_node == parent->get_lf_son_ptr()) {
                    delete parent->get_lf_son_ptr();
                    parent->set_lf_son(nullptr);
                }
                else {
                    delete parent->get_rg_son_ptr();
                    parent->set_rg_son(nullptr);
                }

                removed = true;
            }
            else {
                if (current_node->get_lf_son_ptr() == nullptr) {
                    rotate_left(current_node);
                }
                else if (current_node->get_rg_son_ptr() == nullptr) {
                    rotate_right(current_node);
                }
                else if (current_node->get_lf_son_ptr()->get_key() <= current_node->get_rg_son_ptr()->get_key()) {
                    rotate_left(current_node);
                } else {
                    rotate_right(current_node);
                }
            }
        }
    }
};

int main() {
    srand(time(0));
    std::ios::sync_with_stdio(false);
    fin.tie();
    Treap<int> treap = Treap<int>();
    int n;
    fin >> n;
    for (int i = 0; i < n; ++i) {
        int type, val;
        fin >> type >> val;
        switch (type) {
            case 1:
                treap.insert(val);
                break;
            case 2:
                treap.remove(val);
                break;
            case 3:
                fout << ((treap.find(val) != nullptr) ? 1 : 0) << '\n';
                break;
        }
    }

    std::cout << (double) clock() / CLOCKS_PER_SEC << '\n';
    return 0;
}