Cod sursa(job #2070178)

Utilizator mlc_oficialBoris Barca mlc_oficial Data 19 noiembrie 2017 12:15:40
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.78 kb
#include <fstream>
#include <memory>
#include <iostream>

using namespace std;

class ShuffleTree {
  private:
    struct Node {
        int key;
        Node* son[2];

        Node(const int _key = 0) : key(_key) { }
    };
    
    Node* root;
    int weight;

  public:
    explicit ShuffleTree() : root(nullptr), weight(0) { 
    }

    void Insert(const int key) {
        root = Insert(root, key, rand() % (1 + weight));
    }

    void Erase(const int key) {
        root = Remove(root, key, rand() % (1 + weight));
    }

    bool Find(const int key) const {
        return Find(root, key);
    }
  private:
    bool Find(Node* node, const int key) const {
        if (node == nullptr) {
            return false;
        }

        if (node->key == key) {
            return true;
        }

        return Find(node->son[key < node->key], key);
    }

    Node* Rotate(Node* node, const int idx, const int lambda) {
        if (lambda > 0 or node->son[idx] == nullptr) {
            return node;
        }

        Node* ch = node->son[idx];
        node->son[idx] = ch->son[1 - idx];
        ch->son[1 - idx] = node;
        return ch;
    }

    Node* Insert(Node* node, const int key, const int lambda) {
        if (node == nullptr) {
            weight += 1;
            return new Node(key);
        }
        if (node->key == key) {
            return node;
        }

        const int idx = key < node->key;
        node->son[idx] = Insert(node->son[idx], key, (lambda - 1) / 2); 
        return Rotate(node, idx, lambda);
    }
    
    Node* RemoveMinimum(Node* node, int& value) {
        if (node->son[0] == nullptr) {
            value = node->key;
            return node->son[1];
        }

        node->son[0] = RemoveMinimum(node->son[0], value);
        return node;
    }

    Node* Remove(Node* node, const int key, const int lambda) {
        if (node == nullptr) {
            return node;
        }

        if (node->key == key) {
            weight -= 1;
            if (node->son[1] == nullptr) {
                return node->son[0];
            }

            node->son[1] = RemoveMinimum(node->son[1], node->key);
            return node;
        }

        int idx = key < node->key;
        node->son[idx] = Remove(node->son[idx], key, (lambda - 1) / 2);
        return Rotate(node, idx, lambda);
    }
};

int main() {
#ifdef INFOARENA
    ifstream cin("hashuri.in");
    ofstream cout("hashuri.out");
#endif

    int num_operations; cin >> num_operations;
    ShuffleTree my_set = ShuffleTree();

    while (num_operations--) {
        int op_type, element; cin >> op_type >> element;
        if (op_type == 1) {
            my_set.Insert(element);
        } else if (op_type == 2) {
            my_set.Erase(element);
        } else {
            cout << my_set.Find(element) << '\n';
        }
    }
}