Cod sursa(job #915845)

Utilizator gabipurcaruGabi Purcaru gabipurcaru Data 15 martie 2013 13:24:00
Problema Hashuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.66 kb
#include <fstream>
using namespace std;

template<class T>
class Nod {
private:
    T val;
    Nod *next, *prev;
public:
    T getVal() {
        return val;
    }
    void setVal(T x) {
        val = x;
    }
    Nod* getPrev() {
        return prev;
    }
    void setPrev(Nod *x) {
        prev = x;
    }
    Nod* getNext() {
        return next;
    }
    void setNext(Nod *x) {
        next = x;
    }
};

template<class T>
class List {
private:
    int size;
    Nod<T> *start, *end;
public:
    int getSize() {
        return size;
    }
    Nod<T>* getStart() {
        return start;
    }
    void add(T val) {
        if(size == 0) {
            start = end = new Nod<T>;
            start->setVal(val);
        } else {
            Nod<T> *n = new Nod<T>;
            n->setVal(val);
            n->setPrev(end);
            end->setNext(n);
            end = n;
        }
        size ++;
    }
    void del(T val) {
        if(size == 0) {
            return;
        } else if(size == 1) {
            if(start->getVal() == val) {
                delete start;
                start = end = NULL;
                size --;
            }
        } else {
            Nod<T> *p = start;
            while(p != NULL) {
                if(p->getVal() == val) {
                    if(p->getPrev() != NULL) {
                        p->getPrev()->setNext(p->getNext());
                    }
                    if(p->getNext() != NULL) {
                        p->getNext()->setPrev(p->getPrev());
                    }
                    delete p;
                    size --;
                    return;
                }
                p = p->getNext();
            }
        }
    }
    int search(T val) {
        if(size == 0) {
            return 0;
        } else if(size == 1) {
            return start->getVal() == val;
        } else {
            Nod<T> *p = start;
            while(p != NULL) {
                if(p->getVal() == val) {
                    return 1;
                }
                p = p->getNext();
            }
            return 0;
        }
    }
};

template<class T>
class Hash {
private:
    List<T> *H1;
    List<T> *H2;
    int n1;
    int n2;
    int (*hash_func)(int, T);
    int max_size;

    void rehash(List<T> *l, List<T> *h, int n) {
        Nod<T> *p = l->getStart();
        while(p != NULL) {
            h[hash_func(n, p->getVal())].add(p->getVal());
            p = p->getNext();
            delete p->getPrev();
        }
    }
public:
    Hash(int n, int m, int (h)(int, T)) {
        max_size = 5;
        hash_func = h;
        H1 = new List<T>[n];
        H2 = new List<T>[m];
        n1 = n;
        n2 = m;
    }
    void add(T val) {
        List<T> *a = &H1[hash_func(n1, val)], *b = &H2[hash_func(n2, val)];
        if(a->getSize() > max_size) {
            rehash(a, H2, n2);
        }
        if(b->getSize() > max_size) {
            rehash(b, H1, n1);
        }
        if(a->getSize() < b->getSize()) {
            a->add(val);
        } else {
            b->add(val);
        }
    }
    void del(T val) {
        H1[hash_func(n1, val)].del(val);
        H2[hash_func(n2, val)].del(val);
    }
    int search(T val) {
        return H1[hash_func(n1, val)].search(val)
            || H2[hash_func(n2, val)].search(val);
    }
};

int hash_int(int n, int val) {
    return val % n;
}

int main() {
    ifstream in("hashuri.in");
    ofstream out("hashuri.out");
    Hash<int> h(66047, 96557, hash_int);
    int n, op, v, i;

    in>>n;
    for(i=0; i<n; i++) {
        in>>op>>v;
        if(op == 1) {
            h.add(v);
        } else if(op == 2) {
            h.del(v);
        } else {
            out<<h.search(v)<<'\n';
        }
    }
    return 0;
}