Cod sursa(job #2043190)

Utilizator SebiSebiPirtoaca George Sebastian SebiSebi Data 19 octombrie 2017 18:42:00
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.97 kb
#include <iostream>
#include <fstream>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <assert.h>
using namespace std;

#define RANDM ((1 << 30) - 1)

struct T {
    int value, priority;
    T *left, *right;

    T() {
        value = 0;
        priority = 0;
    }
    T(int _value, int _priority, T* _left, T* _right) {
        this->value = _value;
        this->priority = _priority;
        this->left = _left;
        this->right = _right;
    }
};

T* nil = nullptr;

T* create_node(int value, int priority = -1) {
    if (priority == -1) {
        priority = rand() & RANDM;
    }
    T* node = new T(value, priority, nil, nil);
    return node;
}

void rot_left(T* &node) {
    assert(node->right != nil);
    T* r = node->right;
    node->right = r->left;
    r->left = node;
    node = r;
}

void rot_right(T* &node) {
    assert(node->left != nil);
    T* r = node->left;
    node->left = r->right;
    r->right = node;
    node = r;
}

void balance(T* &node) {
    assert(node != nil);
    if (node->right->priority > node->priority)
        rot_left(node);
    else if (node->left->priority > node->priority)
        rot_right(node);
}

void insert_treap(T* &node, int value) {
    if (node == nil) {
        node = create_node(value);
        return ;
    }
    if (value < node->value)
        insert_treap(node->left, value);
    else
        insert_treap(node->right, value);
    balance(node);
}

int find_treap(T* node, int value) {
    if (node == nil)
        return 0;
    if (node->value == value)
        return 1;
    if (value < node->value)
        return find_treap(node->left, value);
    return find_treap(node->right, value);
}

void erase_treap(T* &node, int value) {
    if (node == nil)
        return ;
    if (node->value == value) {
        if (node->left == nil && node->right == nil) {
            delete node;
            node = nil;
        }
        else if (node->left->priority > node->right->priority) {
            rot_right(node);
            erase_treap(node->right, value);
        }
        else {
            rot_left(node);
            erase_treap(node->left, value);
        }
    }
    else {
        if (value < node->value)
            erase_treap(node->left, value);
        else
            erase_treap(node->right, value);
    }
}

void clear_treap(T* node) {
    if (node == nil)
        return ;
    clear_treap(node->left);
    clear_treap(node->right);
    delete node;
}

int main()
{
    int n, op, x, i;
    ifstream f("hashuri.in");
    ofstream g("hashuri.out");
    f >> n;
    nil = new T(-1, -1, nullptr, nullptr);
    T* root = new T(-1, (1 << 30), nil, nil);
    for (i = 1; i <= n; i++) {
        f >> op >> x;
        if (op == 1) {
            if (find_treap(root, x) == 0)
                insert_treap(root, x);
        }
        else if (op == 2) {
            erase_treap(root, x);
        }
        else {
            g << find_treap(root, x) << '\n';
        }
    }
    g.close();
    clear_treap(root);
    delete nil;
    return 0;
}