Cod sursa(job #1213298)

Utilizator andreiiiiPopa Andrei andreiiii Data 27 iulie 2014 19:16:54
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.88 kb
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <ctime>

using namespace std;

int getrand() {
    int ret = rand() * 32768 + rand();
    if (ret < 0) ret = -ret;
    return ret;
}


class TreapNode {
public:
    const int key, priority;
    TreapNode *left, *right;

    TreapNode(const int _key):
        key(_key),
        priority(getrand()),
        left(NULL),
        right(NULL),
        size(1) {}

    int getsize() const {
        return this == NULL ? 0: size;
    }

    void update() {
        size = 1 + left->getsize() + right->getsize();
    }
private:
    int size;
};

TreapNode* Root;

pair<TreapNode*, TreapNode*> Split(TreapNode* Root, const int x) {
    if (Root == NULL)
        return make_pair((TreapNode*) NULL, (TreapNode*) NULL);

    if (x >= Root->key) {
        pair<TreapNode*, TreapNode*> leftsplit = Split(Root->left, x);
        Root->left = leftsplit.second;
        Root->update();
        leftsplit.second = Root;
        return leftsplit;
    } else {
        pair<TreapNode*, TreapNode*> rightsplit = Split(Root->right, x);
        Root->right = rightsplit.first;
        Root->update();
        rightsplit.first = Root;
        return rightsplit;
    }
}

TreapNode* Merge(TreapNode* Left, TreapNode *Right) {
    if (Left == NULL)
        return Right;

    if (Right == NULL)
        return Left;

    if (Left->priority > Right->priority) {
        Left->right = Merge(Left->right, Right);
        Left->update();
        return Left;
    } else {
        Right->left = Merge(Left, Right->left);
        Right->update();
        return Right;
    }
}

bool Find(TreapNode* node, const int x) {
    if (node == NULL)
        return false;

    if (x < node->key)
        return Find(node->left, x);
    else if (x > node->key)
        return Find(node->right, x);

    return true;
}

TreapNode *Insert(TreapNode* Root, const int x) {
    if (Find(Root, x))
        return Root;

    pair<TreapNode*, TreapNode*> split = Split(Root, x);
    return Merge(Merge(split.first, new TreapNode(x)), split.second);
}

TreapNode *Remove(TreapNode* Root, const int x) {
    if (Root == NULL)
        return NULL;

    if (x < Root->key) {
        Root->left = Remove(Root->left, x);
        Root->update();
        return Root;
    } else if (x > Root->key) {
        Root->right = Remove(Root->right, x);
        Root->update();
        return Root;
    } else {
        TreapNode* t = Merge(Root->left, Root->right);
        delete Root;
        return t;
    }
}

int main() {
    freopen("hashuri.in", "r", stdin);
    freopen("hashuri.out", "w", stdout);

    int Q;
    scanf("%d", &Q);

    srand(0);

    TreapNode *T;

    while (Q--) {
        int op, x;
        scanf("%d%d", &op, &x);

        if (op == 1) {
            T = Insert(T, x);
        } else if (op == 2) {
            T = Remove(T, x);
        } else {
            printf("%d\n", int(Find(T, x)));
        }
    }
}