Cod sursa(job #1228068)

Utilizator klamathixMihai Calancea klamathix Data 12 septembrie 2014 16:50:11
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.86 kb
#include <bits/stdc++.h>
const int offset = 50;
using namespace std;

template<class T, class HashFunction = std::hash<T>>
class CuckooHash {
    public:
        
    void reHash() {
        if(2 * KeyCount  >= HashSize) {
            for(int i = 0; i < 2; ++i) 
                p[i] = 3 * KeyCount + 1 + rand() % 10;
        }
        resetLinearHashes();
        vector<T> aux;
        for(int i = 0; i < (int) HashSize; ++i)
            if(Table[i] != T())
                aux.push_back(Table[i]);

        HashSize = p[1] + 1;
        Table = vector<T> (HashSize, T());
        for(auto tmp : aux)
            insert(tmp);
    }

    void insert(T X, int steps = 0) {
        if(steps > 20)
            reHash();
        if(lookUp(X) != -1)
            return;
        unsigned int key = X;
        unsigned int poz[2] = {0, 0};
        
        for(int i = 0; i < 2; ++i)
            poz[i] = (a[i] * key + b[i]) % p[i];

        if(Table[poz[0]] == T())
            Table[poz[0]] = X;
        else if(Table[poz[1]] == T())
            Table[poz[1]] = X;
        else {
            T tmp = Table[poz[1]];
            Table[poz[1]] = X;
            insert(tmp, steps + 1);
        }
        KeyCount++;
    }
    
    int lookUp(T X) {
        unsigned int key = hasher(X);
        unsigned int poz[2] = {0, 0};
        for(int i = 0; i < 2; ++i)
            poz[i] = (a[i] * key + b[i]) % p[i];
        if(Table[poz[0]] != T() && (Table[poz[0]]) == X)
            return poz[0];
        if(Table[poz[1]] != T() && (Table[poz[1]]) == X)
            return poz[1];
        return -1;
    }

    void erase(T X) {
        int tmp = lookUp(X);
        if(tmp == -1)
            return;
        Table[tmp] = T();
        KeyCount--;
    }

    CuckooHash(vector<T> A = vector<T>()) {
        unsigned int sz = A.size();
        p[0] = 37, p[1] = 43;
        while(3 * sz >= p[0])
            p[0] = p[0] * 2 + 1;
        while(3 * sz >= p[1])
            p[1] = p[1] * 2 + 1;
        if(p[1] < p[0])
            swap(p[0], p[1]);
        resetLinearHashes();
        HashSize = p[1];
        Table = vector<T>(HashSize, T());
        for(auto tmp : A)
            insert(tmp);
        KeyCount = sz;
    };

    private:
    HashFunction hasher;
    vector<T> Table;
    unsigned int p[2], a[2], b[2];
    unsigned int HashSize;
    unsigned int KeyCount;

    void resetLinearHashes() {
        for(int i = 0; i < 2; ++i) {
            a[i] = 1 + rand();
            b[i] = 1 + rand();
        }
    }
};

int main() {
    
    ifstream cin("hashuri.in");
    ofstream cout("hashuri.out");

    srand(time(0));
    CuckooHash<int> H;

    int OpCount; cin >> OpCount;
    for(int i = 0; i < OpCount; ++i) {
        //cerr << i << "\n";
        int Type, X; cin >> Type >> X;
        if(Type == 1)
            H.insert(X);
        else if(Type == 2)
            H.erase(X);
        else cout << (H.lookUp(X) != -1) << "\n";
    }
}