Cod sursa(job #2024233)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 20 septembrie 2017 10:30:37
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.03 kb
#include <bits/stdc++.h>

using namespace std;

const int max_prior = INT_MAX;

int get_random(int lim)
{
    long long val = (rand() << 25LL) + (rand() << 20LL) + (rand() << 10LL) + (rand() ^ 7528529) + (rand() ^ 257982) + rand();
    val %= lim;
    if (val < 0) val += lim;
    return (int) val + 1;
}


struct treap {
    double key; int prior;
    treap *left, *right;

    treap() {
        key = 0; prior = 0;
        left = NULL; right = NULL;
    }

    treap(double key, int prior, treap *left, treap *right) {
        this -> key = key; this -> prior = prior;
        this -> left = left; this -> right = right;
    }
};

treap *null;

void treap_rotateL(treap *&T) {
    treap *aux = T -> left;
    T -> left = aux -> right;
    aux -> right = T;

    T = aux;
}

void treap_rotateR(treap *&T) {
    treap *aux = T -> right;
    T -> right = aux -> left;
    aux -> left = T;

    T = aux;
}

void treap_balance(treap *&T) {
    if (T -> left -> prior > T -> prior)
        treap_rotateL(T);
    else if (T -> right -> prior > T -> prior)
        treap_rotateR(T);
}

void treap_insert(treap *&T, double key, int prior) {
    if (T == null) {
        T = new treap(key, prior, null, null);
        return;
    }

    if (key < T -> key)
        treap_insert(T -> left, key, prior);
    else if (key > T -> key)
        treap_insert(T -> right, key, prior);

    treap_balance(T);
}

void treap_erase(treap *&T) {
    if (T -> left == null && T -> right == null) {
        delete T; T = null;
        return;
    }

    if (T -> left -> prior > T -> right -> prior)
        treap_rotateL(T);
    else treap_rotateR(T);

    if (T -> left -> key == -1)
        treap_erase(T -> left);
    else treap_erase(T -> right);
}

void split(treap *&T, treap *&T2, double key) {
    treap_insert(T, key + 0.5, max_prior);
    T2 = T -> right;
    T = T -> left;
}

void join(treap *&root, treap *&T1, treap *&T2) {
    root = new treap(-1, 0, T1, T2);
    treap_erase(root);
}

void treap_erase(treap *&T, double low_key, double high_key) {
    treap *A = T, *B, *C;
    split(A, B, low_key - 1);
    split(B, C, high_key);
    join(T, A, C);
}

bool treap_find(treap *T, double key) {
    if (T == null) return 0;

    if (key < T -> key)
        return treap_find(T -> left, key);
    else if (T -> key < key)
        return treap_find(T -> right, key);

    return 1;
}

int main() {
    ifstream fin("hashuri.in");
    ofstream fout("hashuri.out");

    srand(time(0));
    treap *root = null = new treap(0, 0, NULL, NULL);

    int n; fin >> n;
    for (int i = 1; i <= n; ++i) {
        int type, x;

        fin >> type;
        if (type == 1) {
            fin >> x;
            treap_insert(root, x, get_random(1e9));
        }
        if (type == 2) {
            fin >> x;
            treap_erase(root, x, x);
        }
        if (type == 3) {
            fin >> x;
            fout << treap_find(root, x) << '\n';
        }
    }

    return 0;
}