Cod sursa(job #1228135)

Utilizator klamathixMihai Calancea klamathix Data 12 septembrie 2014 18:59:38
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.1 kb
#include <bits/stdc++.h>
const int offset = 50;
using namespace std;
 
template<class T, class HashFunction = std::hash<T>>
class CuckooHash {
    public:
    
    void insertElement(T X) {
        insert(X, -1);
    }
     
    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]] != 0 && (Table[poz[0]]) == X)
            return poz[0];
        if(Table[poz[1]] != 0 && (Table[poz[1]]) == X)
            return poz[1];
        return -1;
    }
 
    void eraseElement(T X) {
        int tmp = lookUp(X);
        if(tmp == -1)
            return;
        Table[tmp] = 0;
        KeyCount--;
    }
 
    CuckooHash(vector<T> A = vector<T>()) {
        unsigned int sz = A.size();
        p[0] = 3000037, p[1] = 3000039;

        resetLinearHashes();
        HashSize = p[1];
        Table = vector<T>(HashSize, T());
        for(auto tmp : A)
            insert(tmp, -1);
        KeyCount = sz;
    };
 
    private:
    HashFunction hasher;
    vector<T> Table;
    unsigned int p[2], a[2], b[2];
    unsigned int HashSize;
    unsigned int KeyCount;
        
    bool prime(int x) {
        for(int i = 2; i * i <= x; ++i)
            if(x % i == 0)
                return false;
        return true;
    }
    
     void insert(T X, T last, int steps = 0) {
        if(steps > 20) 
            reHash();

        if(lookUp(X) != -1)
            return;
        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]] == 0)
            Table[poz[0]] = X;
        else if(Table[poz[1]] == 0)
            Table[poz[1]] = X;
        else {
            int t = 0;
            if(Table[poz[t]] == last)
                t = 1 - t;
            T tmp = Table[poz[t]];
            Table[poz[t]] = X;
            insert(tmp, X, steps + 1);
        }
        KeyCount++;
    }
    
    void reHash() {
        resetLinearHashes();
        vector<T> aux(KeyCount);
        int cnt = 0;

        for(int i = 0; i < (int) HashSize; ++i) {
            if(Table[i] != T())
                aux[cnt++] = Table[i];
            Table[i] = T();
        }

        HashSize = p[1] + 1;
        for(auto tmp : aux)
            insert(tmp, -1);
        aux.clear();
    }
    
    int getRandomPrime() {
        int start = rand();
        while(!prime(start))
            start = rand();
        return start;
    }
    void resetLinearHashes() {
        for(int i = 0; i < 2; ++i) {
            a[i] = getRandomPrime();
            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.insertElement(X);
        else if(Type == 2)
            H.eraseElement(X);
        else cout << (H.lookUp(X) != -1) << "\n";
    }
}