Cod sursa(job #2023118)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 18 septembrie 2017 12:15:00
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.97 kb
#include <bits/stdc++.h>

using namespace std;

class InParser {
private:
    FILE *fin;
    char *buff;
    int sp;

    char read_ch() {
        ++sp;
        if (sp == 4096) {
            sp = 0;
            fread(buff, 1, 4096, fin);
        }
        return buff[sp];
    }

public:
    InParser(const char* nume) {
        fin = fopen(nume, "r");
        buff = new char[4096]();
        sp = 4095;
    }

    InParser& operator >> (int &n) {
        char c;
        while (!isdigit(c = read_ch()) && c != '-');
        int sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }

    InParser& operator >> (long long &n) {
        char c;
        n = 0;
        while (!isdigit(c = read_ch()) && c != '-');
        long long sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
};

int get_random(int lim)
{
    srand(time(0));

    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 {
    int key, prior;
    treap *left, *right;

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

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

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 != NULL && T -> left -> prior > T -> prior)
        treap_rotateL(T);
    else if (T -> right != NULL && T -> right -> prior > T -> prior)
        treap_rotateR(T);
}

void treap_insert(treap *&T, int 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, int key) {
    if (T == NULL) return;

    if (key < T -> key)
        treap_erase(T -> left, key);
    else if (key > T -> key)
        treap_erase(T -> right, key);
    else {
        if (T -> left == NULL && T -> right == NULL) {
            delete T;
            T = NULL;
        }
        else {
            if (T -> right == NULL || (T -> left != NULL && T -> left -> prior > T -> right -> prior))
                treap_rotateL(T);
            else treap_rotateR(T);

            treap_erase(T, key);
        }
    }
}

bool treap_find(treap *T, int 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");

    treap *root = 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);
        }
        if (type == 3) {
            fin >> x;
            fout << treap_find(root, x) << '\n';
        }
    }

    return 0;
}