Cod sursa(job #1768023)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 30 septembrie 2016 02:52:42
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 6.65 kb
/**
Author       : Gabriel-Robert Inelus
University   : University of Oxford
Year of study: 2
*/
#include <bits/stdc++.h>

using namespace std;

const int minusInfinity = INT_MIN;
const int plusInfinity = INT_MAX;

template <typename T>
struct totalOderLessOrEqual{
    bool operator()(const T &elem1, const T &elem2) const
    {
        return elem1 <= elem2;
    }
};

struct Node{
    Node *left;
    Node *right;
    int priority;

    Node()
    {
        left = right = 0;
        priority = minusInfinity;
    }

    Node(Node *_left, Node *_right, int _priority)
    {
        left = _left;
        right = _right;
        priority = _priority;
    }
};

template <typename T>
struct NodeWithKey : Node{
    T key;

    NodeWithKey(T _key)
    {
        left = right = 0;
        priority = minusInfinity;
        key = _key;
    }

    NodeWithKey(Node *_left, Node *_right, int _priority, T _key)
    {
        left = _left;
        right = _right;
        priority = _priority;
        key = _key;
    }
};

template <typename T, typename totalBinaryRelation>
class Treap{
private:
    Node *fakeRoot;
    Node *nil;
    void rotateLeft(Node *&k);
    void rotateRight(Node *&k);
    void balanceTreap(Node *&k);
    void insert(Node *&k, T element);
    void erase(Node *&k, T element);
    bool search(Node *k, T element);
    void inOrderTraversal(Node *k, vector<T> *container);
public:
    Treap()
    {
        srand(time(0));
        nil = new Node;
        nil->left = nil;
        nil->right = nil;
        fakeRoot = new Node(nil, nil, plusInfinity);
    }
    void insert(T element);
    void insert(auto begin, auto end);

    void erase(T element);
    void erase(auto begin, auto end);

    bool search(T element);

    void inOrderTraversal(vector<T> *container);
};

template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::rotateRight(Node *&k)
{
    Node *aux = k->left;
    k->left = aux->right;
    aux->right = k;
    k = aux;
}

template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::rotateLeft(Node *&k)
{
    Node *aux = k->right;
    k->right = aux->left;
    aux->left = k;
    k = aux;
}

template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::balanceTreap(Node *&k)
{
    if(k->left->priority > k->right->priority && k->left->priority > k->priority)
        rotateRight(k);
    else
        if(k->left->priority < k->right->priority && k->right->priority > k->priority)
            rotateLeft(k);
}

template <typename T, typename totalBinaryRelation>
bool Treap<T, totalBinaryRelation>::search(Node *k, T element)
{
    if (k == nil)
        return false;
    NodeWithKey<T> *aux = static_cast<NodeWithKey<T> *>(k);
    if (totalBinaryRelation()(aux->key, element) &&
        totalBinaryRelation()(element, aux->key))
        return true;
    if (totalBinaryRelation()(element, aux->key))
        return search(k->left, element);
    return search(k->right, element);
}
template <typename T, typename totalBinaryRelation>
bool Treap<T, totalBinaryRelation>::search(T element)
{
    return search(fakeRoot->left, element);
}

template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::insert(Node *&k, T element)
{
    if (k == nil) {
        k = new NodeWithKey<T>(nil, nil, rand(), element);
        return;
    }
    NodeWithKey<T> *aux = static_cast<NodeWithKey<T> *>(k);
    if (totalBinaryRelation()(element, aux->key))
        insert(k->left, element);
    else
        insert(k->right, element);
    balanceTreap(k);
}
template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::insert(T element)
{
    insert(fakeRoot->left, element);
}
template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::insert(auto begin, auto end)
{
    while (begin != end) {
        insert(*begin);
        ++begin;
    }
}


template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::erase(Node *&k, T element)
{
    NodeWithKey<T> *aux = static_cast<NodeWithKey<T> *>(k);
    if (totalBinaryRelation()(element, aux->key) &&
        totalBinaryRelation()(element, aux->key)) {
        if (k->left == nil && k->right == nil) {
            Node *deleter = k;
            k = nil;
            delete deleter;
            return;
        }
        if (k->left->priority > k->right->priority) {
            rotateRight(k);
            erase(k->right, element);
        }
        else {
            rotateLeft(k);
            erase(k->left, element);
        }
        return;
    }

    if (totalBinaryRelation()(element, aux->key))
        erase(k->left, element);
    else
        erase(k->right, element);
}
template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::erase(T element)
{
    erase(fakeRoot->left, element);
}
template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::erase(auto begin, auto end)
{
    while(begin != end) {
        erase(*begin);
        ++begin;
    }
}

template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::inOrderTraversal(Node *k, vector<T> *container)
{
    if (k == nil)
        return;
    inOrderTraversal(k->left, container);
    container->push_back(static_cast<NodeWithKey<T> *>(k)->key);
    inOrderTraversal(k->right, container);
}
template <typename T, typename totalBinaryRelation>
void Treap<T, totalBinaryRelation>::inOrderTraversal(vector<T> *container)
{
    inOrderTraversal(fakeRoot->left, container);
}

#define DIM 66613
char buffer[DIM];
int poz = DIM - 1;

void scan(int &A)
{
    A = 0;
    while('0' > buffer[poz] || buffer[poz] > '9')
        if(++poz == DIM) fread(buffer,1,DIM,stdin),poz = 0;
    while('0' <= buffer[poz] && buffer[poz] <= '9')
    {
        A = A * 10 + buffer[poz] - 48;
        if(++poz == DIM)
            fread(buffer,1,DIM,stdin),poz = 0;
    }
}



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

    Treap<int, totalOderLessOrEqual<int> > treap;
    int N,op,x;
    scan(N);
    for (int i = 0; i < N; ++i) {
        scan(op);scan(x);
        if (op == 1) {
            if(treap.search(x))
                continue;
            treap.insert(x);
            continue;
        }
        if (op == 2) {
            if(!treap.search(x))
                continue;
            treap.erase(x);
            continue;
        }
        printf("%d\n",treap.search(x));
    }

    return 0;
}