Cod sursa(job #907548)

Utilizator maritimCristian Lambru maritim Data 8 martie 2013 00:36:31
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 4.26 kb
#include<iostream>
#include<vector>
#include<stdlib.h>
#include<time.h>
#include<fstream>
#include<ctype.h>
using namespace std;
 
class CuckooHash
{
    private:
        int hash1,hash2,M1,M2,size,limit;
        int uninserted,prime;
        int  *Hash1,*Hash2;
 
        void makeSizes(void);
        int hashFunction1(int x);
        int hashFunction2(int x);
        void remakeFunctions(void);
        int reinsert(int x);
        int rehash(void);
        int insertTry(int x);
 
    public:
        CuckooHash(void);
        CuckooHash(int M1,int M2);
        int insert(int x);
        int remove(int x);
        int find(int x);
};
 
CuckooHash::CuckooHash(void)
{
    srand(time(NULL));
 
    makeSizes();
 
    prime = 1000000009;
 
    Hash1 = new int[2000000];
    Hash2 = new int[2000000];
 
    remakeFunctions();
}
 
CuckooHash::CuckooHash(int M1,int M2)
{
    this->M1 = M1;
    this->M2 = M2;
 
    prime = 1000000009;
 
    Hash1 = new int[1500000];
    Hash2 = new int[1500000];
 
    remakeFunctions();
}
 
int CuckooHash::hashFunction1(int x)
{
    return ((1LL*hash1*x+hash2)%prime)%M1;
}
 
int CuckooHash::hashFunction2(int x)
{
    return ((1LL*hash2*x+hash1)%prime)%M2;
}
 
void CuckooHash::remakeFunctions(void)
{
    hash1 = rand()%M1;
    hash2 = rand()%M2;
}
 
void CuckooHash::makeSizes(void)
{
    this->M1 = 1500000 + rand()%500000;
    this->M2 = 1500000 + rand()%500000;
 
    this->M1 += 1-(this->M1 & 1);
    this->M2 += 1-(this->M2 & 1);
 
}
 
inline int CuckooHash::rehash(void)
{
    vector<int> aux;
     
    aux.push_back(uninserted);
 
    for(int i=0;i<M1;i++)
        if(Hash1[i])
            aux.push_back(Hash1[i]);
 
    for(int i=0;i<M2;i++)
        if(Hash2[i])
            aux.push_back(Hash2[i]);
 
    int i = aux.size()-2;
 
    for(;;)
    {
       for(i++;i>=0;i--)
            remove(aux[i]);
 
        makeSizes();
        remakeFunctions();
 
        for(i=0;i<aux.size();i++)
            if(!insertTry(aux[i]))
                break;
 
        if(i == aux.size())
        {
            aux.clear();
            return 1;
        }
    }

    return 0;
}
 
inline int CuckooHash::reinsert(int x)
{
    int hash_funct2 = hashFunction2(x);
 
    if(size == 0)
    {
        uninserted = x;
        return 0;
    }
 
    if(Hash2[hash_funct2])
    {
        int y = Hash2[hash_funct2];
        Hash2[hash_funct2] = x;
        -- size;
        return reinsert(y);
    }
    else
    {
        Hash2[hash_funct2] = x;
        return 1;
    }
}
 
inline int CuckooHash::insertTry(int x)
{
    int hash_funct1 = hashFunction1(x);
 
    if(find(x))
    {
        return 1;
    }
 
    if(Hash1[hash_funct1])
    {
        int y = Hash1[hash_funct1];
        Hash1[hash_funct1] = x;
        size = 20;
        return reinsert(y);
    }
    else
    {
        Hash1[hash_funct1] = x;
        return 1;
    }
}
 
inline int CuckooHash::insert(int x)
{
    if(!insertTry(x))
    {
        rehash();
    }
 
    return 1;
}
 
inline int CuckooHash::remove(int x)
{
    int hash_funct1 = hashFunction1(x);
    int hash_funct2 = hashFunction2(x);
 
    if(Hash1[hash_funct1] == x)
    {
        Hash1[hash_funct1] = 0;
        return 1;
    }
    else if(Hash2[hash_funct2] == x)
    {
        Hash2[hash_funct2] = 0;
        return 1;
    }
 
    return -1;
}
 
inline int CuckooHash::find(int x)
{
    int hash_funct1 = hashFunction1(x);
    int hash_funct2 = hashFunction2(x);
 
    if(Hash1[hash_funct1] == x)
    {
        return 1;
    }
    else if(Hash2[hash_funct2] == x)
    {
        return 1;
    }
 
    return 0;
}
 
//int SolV[1000002];
//char S[10000002];
 
/*inline int getInt(int *i)
{
    int rez = 0;
 
    for(;!isdigit(S[*i]);++(*i));
    for(;isdigit(S[*i]);rez = rez*10+(S[*i])-'0',++(*i));
 
    return rez;
}*/
 
int main()
{
    ifstream f("hashuri.in");
    ofstream g("hashuri.out");
 
//    f.getline(S,sizeof(S),EOF);
 
    int N,op,a,k = 0;
    //SolV[0] = 0;
 
    CuckooHash Hash;
 
//    N = getInt(&k);
 
    f >> N;
 
    for(int i=1;i<=N;i++)
    {
//        op = getInt(&k);
//        a = getInt(&k);
        f >> op >> a;
         
        switch(op)
        {
            case 1 : Hash.insert(a);
                break;
            case 2 : Hash.remove(a);
                break;
            case 3 : g << Hash.find(a) << "\n";
        }
    }
 
    f.close();
    g.close();
}