Pagini recente » Cod sursa (job #2802936) | Cod sursa (job #2314637) | Cod sursa (job #1518765) | Cod sursa (job #1286403) | Cod sursa (job #2260096)
#include <fstream>
#include <random>
#include <memory>
#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_;
shared_ptr<TreapNode<T>> lf_son_, rg_son_, parent_;
public:
TreapNode(shared_ptr<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_ = generator(mt);
// key_ = rand() % kInf;
}
}
T get_value() const {
return value_;
}
int get_key() const {
return key_;
}
shared_ptr<TreapNode<T>> get_parent_ptr() const {
return parent_;
}
shared_ptr<TreapNode<T>> get_lf_son_ptr() const {
return lf_son_;
}
shared_ptr<TreapNode<T>> get_rg_son_ptr() const {
return rg_son_;
}
void set_lf_son(shared_ptr<TreapNode<T>> son) {
lf_son_ = son;
}
void set_rg_son(shared_ptr<TreapNode<T>> son) {
rg_son_ = son;
}
void set_parent(shared_ptr<TreapNode<T>> parent) {
parent_ = parent;
}
};
template <typename T>
class Treap {
private:
shared_ptr<TreapNode<T>> root_;
void rotate_left(const shared_ptr<TreapNode<T>> &node_ptr) {
shared_ptr<TreapNode<T>> 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(const shared_ptr<TreapNode<T>> &node_ptr) {
shared_ptr<TreapNode<T>> 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_ = make_shared<TreapNode<T>>(nullptr, T());
}
void insert(T val) {
// Treap is empty
if (root_->get_lf_son_ptr() == nullptr) {
root_->set_lf_son(make_shared<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(make_shared<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(make_shared<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;
}
}
std::shared_ptr<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(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()) {
parent->set_lf_son(nullptr);
}
else {
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() {
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;
}
}
return 0;
}