Cod sursa(job #940778)

Utilizator R.A.RFMI Romila Remus Arthur R.A.R Data 17 aprilie 2013 02:18:58
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 5.06 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <time.h>
#include <stdlib.h>
#include <string>

using namespace std;


class CuckooBase
{
protected:
        int *Hash1,*Hash2;
        int *Op;
        int RM,C1, C2, T1, T2,Disp1,Disp2,K;
        void Generate();
        void Rehash();
        bool Add(int);// au ca parametru pozitia din vector
        bool Find(int);
        void Insert(int);
        void Delete(int);
        void Swap(int &a,int &b){int c = a; a = b; b = c;}
        virtual bool Egal (int,int) {return 0;};
        virtual int  Push (int)     {return 0;};
        virtual int  Push (double)  {return 0;};
        virtual int  Push (string)  {return 0;};
        virtual int  F1   (int)     {return 0;};//functiile de dispersie au ca parametru pozitia din vector
        virtual int  F2   (int)     {return 0;};
public:
        CuckooBase(int);
        ~CuckooBase();
        bool operator ==    (int a)     {int p = Push(a);Op[p] = 3;return Find(p);}
        void operator +     (int a)     {int p = Push(a);Op[p] = 1;Insert(p);}
        void operator -     (int a)     {int p = Push(a);Op[p] = 2,Delete(p);}
        bool operator ==    (double a)  {int p = Push(a);Op[p] = 3;return Find(p);}
        void operator +     (double a)  {int p = Push(a);Op[p] = 1;Insert(p);}
        void operator -     (double a)  {int p = Push(a);Op[p] = 2,Delete(p);}
        bool operator ==    (string a)  {int p = Push(a);Op[p] = 3;return Find(p);}
        void operator +     (string a)  {int p = Push(a);Op[p] = 1;Insert(p);}
        void operator -     (string a)  {int p = Push(a);Op[p] = 2,Delete(p);}
};


CuckooBase::CuckooBase(int N=100000):RM(29),C1(1311237),C2(1212041),T1(300000),T2(300000),K(0)
{
    Generate();
    Hash1 = new int[Disp1+10];
    Hash2 = new int[Disp2+10];
    Op = new int[N+1];
}

CuckooBase::~CuckooBase()
{
    delete[] Hash1;
    delete[] Hash2;
    delete[] Op;
}

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

bool CuckooBase::Find(int p)
{
    int key1 = F1(p), key2 = F2(p);
    if(Egal(Hash1[key1],p) || Egal(Hash2[key2],p))
        return 1;
    return 0;
}

void CuckooBase::Delete(int p)
{
    int key1 = F1(p), key2 = F2(p);
    if(Egal(Hash1[key1],p))
        Hash1[key1] = 0;
    if(Egal(Hash2[key2],p))
        Hash2[key2] = 0;
}

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

void CuckooBase::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] == 1)
            if(!Find(i)&&!Add(i))
             {
                Rehash();
                return;
             }
        if(Op[i] == 2)
            Delete(i);
    }
}

void CuckooBase::Insert(int p)
{
    if(!Find(p)&&!Add(p))
            Rehash();
}


class CuckooInt:public CuckooBase
{
    int *Nr;
    int Push(int nr){Nr[++K] = nr;return K;}
    bool Egal(int p1,int p2){if(Nr[p1] == Nr[p2])return 1;return 0;}

    int F1(int p){return Nr[p]%Disp1;}
    int F2(int p){return Nr[p]%Disp2;}

public:
    CuckooInt(int N):CuckooBase(N){Nr = new int[N+1];}
    ~CuckooInt(){delete[] Nr;}

};

class CuckooDouble:public CuckooBase
{
    double *Nr;
    int Push(double nr){Nr[++K] = nr;return K;}
    bool Egal(int p1,int p2){if(Nr[p1] == Nr[p2])return 1;return 0;}

    int F1(int p){long long ret = (long long)((Nr[p]*0.618034)*1000000)%Disp1;return (int)ret;}
    int F2(int p){long long ret = (long long)((Nr[p]*0.618034)*1000000)%Disp2;return (int)ret;}

public:
    CuckooDouble(int N):CuckooBase(N){Nr = new double[N+1];}
    ~CuckooDouble(){delete[] Nr;}

};

class CuckooString:public CuckooBase
{
    string *Nr;
    int Push(string nr){Nr[++K] = nr;return K;}
    bool Egal(int p1,int p2){if(Nr[p1] == Nr[p2])return 1;return 0;}

    int F1(int p){int r=0,i;for(i=0;i<Nr[p].size();i++)r = ((r*131+Nr[p][i])%Disp1);return r;}
    int F2(int p){int r=0,i;for(i=0;i<Nr[p].size();i++)r = ((r*131+Nr[p][i])%Disp2);return r;}

public:
    CuckooString(int N):CuckooBase(N){Nr = new string[N+1];}
    ~CuckooString(){delete[] Nr;}

};


int main()
{
    int x;
    int op,N;
    ifstream in("hashuri.in");
    ofstream out("hashuri.out");
    cout<<"1. Hashuri de stringuri.\n";
    cout<<"2. Hashuri de inturi.\n";
    cout<<"3. Hashuri de double.\n";
    //cin>>op;
    in>>N;
    CuckooBase *A;
    A = new CuckooInt(N);
    while(N--)
    {
        in>>op>>x;
        if(op==1)
            *A+x;
        if(op==2)
            *A-x;
        if(op==3)
        {
            if(*A==x)
                 out<<"1\n";
            else out<<"0\n";
        }
    }
    return 0;
}