Cod sursa(job #906366)

Utilizator maritimCristian Lambru maritim Data 6 martie 2013 19:31:09
Problema Hashuri Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 3.01 kb
#include<iostream>
#include<vector>
#include<stdlib.h>
#include<time.h>
#include<fstream>
using namespace std;

class CuckooHash
{
    private:
        int hash1,hash2,M1,M2,size;
        vector<int>  Hash1,Hash2;

        int hashFunction1(int x);
        int hashFunction2(int x);
        void makeFunctions(void);
        int reinsert(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));

    this->M1 = 1000014 + rand()%200111;
    this->M2 = 1000014 + rand()%200111;

    this->M1 += 1-(this->M1 & 1);
    this->M2 += 1-(this->M2 & 1);

    Hash1.resize(M1);
    Hash2.resize(M2);

    makeFunctions();
}

CuckooHash::CuckooHash(int M1,int M2)
{
    this->M1 = M1;
    this->M2 = M2;

    Hash1.resize(M1);
    Hash2.resize(M2);

    makeFunctions();
}

int CuckooHash::hashFunction1(int x)
{
    return (1LL*hash1*x+hash2)%M1;
}

int CuckooHash::hashFunction2(int x)
{
    return (1LL*hash2*x+hash1)%M2;
}

void CuckooHash::makeFunctions(void)
{
    srand(time(NULL));

    hash1 = (M1>>1) + rand()%(M1>>1);
    hash2 = (M2>>1) + rand()%(M2>>1);
}

inline int CuckooHash::reinsert(int x)
{
    int hash_funct2 = hashFunction2(x);

    if(size == 0)
    {
        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::insert(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 = 7;
        return reinsert(y);
    }
    else
    {
        Hash1[hash_funct1] = x;
        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 Rezolvare()
{
    int N,op,a;

    CuckooHash Hash;

    ifstream f("hashuri.in");
    ofstream g("hashuri.out");

    f >> N;

    for(int i=1;i<=N;i++)
    {
        f >> op >> a;
        
        switch(op)
        {
            case 1 : { 
                if(!Hash.insert(a))
                    return 0; }
                break;
            case 2 : Hash.remove(a);
                break;
            case 3 : g << Hash.find(a) << "\n";
        }
    }

    f.close();
    g.close();

    return 1;
}

int main()
{
    for(;!Rezolvare(););
}