Cod sursa(job #917820)

Utilizator R.A.RFMI Romila Remus Arthur R.A.R Data 18 martie 2013 13:15:32
Problema Hashuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.4 kb
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdlib.h>

using namespace std;

class Cuckoo
{
private:
        int RM,C1, C2, T1, T2;
        int *Hash1,*Hash2,*Nr,Disp1,Disp2,K;
        bool *Op;
        bool Add(int);
        void Rehash();
        void Generate();
        int F1(int nr){return nr%Disp1;};
        int F2(int nr){return nr%Disp2;};
        void Swap(int &a,int &b){int c = a; a = b; b = c;}

public:
        Cuckoo(int);
        void Insert(int);
        bool Find(int);
        void Delete(int);
};

void Cuckoo::Generate()
{
    Disp1 = C1 + rand()%T1;
    Disp2 = C2 + rand()%T2;
}

Cuckoo::Cuckoo(int N = 1000000)
{
    RM = 29, C1 = 1211237, C2 = 912041, T1 = 1000000, T2 = 200000;
    srand(time(NULL));
    Generate();
    Hash1 = new int[Disp1+1];
    Hash2 = new int[Disp2+1];
    Op = new bool[N+1];
    Nr = new int[N+1];
    K = 0;
}

bool Cuckoo::Add(int nr)
{
    int i;
    for(i=1;i<=RM;i++)
    {
        if(Hash1[F1(nr)] == 0)
        {
            Hash1[F1(nr)] = nr;
            return 1;
        }
        Swap(nr,Hash1[F1(nr)]);
        if(Hash2[F2(nr)] ==0)
        {
            Hash2[F2(nr)] = nr;
            return 1;
        }
        Swap(nr,Hash2[F2(nr)]);
    }
    return 0;
}

void Cuckoo::Insert(int nr)
{
    Op[++K] = 1, Nr[K] = nr;
    if(!Add(nr))
        Rehash();
}

void Cuckoo::Delete(int nr)
{
    Op[++K] = 0, Nr[K] = nr;
    int v1 = F1(nr), v2 = F2(nr);
    if(Hash1[v1] == nr)
        Hash1[v1] = 0;
    if(Hash2[v2] == nr)
        Hash2[v2] = 0;
}

void Cuckoo::Rehash()
{
    delete Hash1;
    delete Hash2;
    Generate();
    Hash1 = new int[Disp1+1];
    Hash2 = new int[Disp2+1];
    for(int i=1;i<=K;i++)
    {
        if(Op[i])
        {
            if(!Find(Nr[i]))
             if(!Add(Nr[i]))
                Rehash();
        }
        else Delete(Nr[i]);
    }
}

bool Cuckoo::Find(int nr)
{
    int v1 = F1(nr), v2 = F2(nr);
    if(Hash1[v1] == nr || Hash2[v2] == nr)
        return 1;
    return 0;
}


int main()
{
    int x,op,N;
    ifstream in("hashuri.in");
    ofstream out("hashuri.out");
    in>>N;
    Cuckoo A(N);
    while(N--)
    {
        in>>op>>x;
        if(op==1)
            A.Insert(x);
        if(op==2)
            A.Delete(x);
        if(op==3)
            out<<A.Find(x)<<'\n';
    }
    return 0;
}