Cod sursa(job #922178)

Utilizator razvan9310FMI - Razvan Damachi razvan9310 Data 21 martie 2013 22:52:53
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 5.49 kb
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <typeinfo>
#include <sstream>
#define prim 1000000009
using namespace std;
 
template<class type> class Cuckoo
{
    private:
        unsigned int a1, a2, b1, b2;
        unsigned int size, *H1, *H2;
		
		//Trateaza orice input ca string, pe care-l converteste polinomial in numar
		//In felul asta, hashul poate primi orice tip de date (alta metoda mai eficienta???)
		unsigned int parse(type val)
		{
			ostringstream convert; convert<<val;
			string str = convert.str();
			unsigned int result=1<<31, i, SIZE=str.size(), xorVal, primescu=16777619;
			for (i=0; i<SIZE; ++i)
				//result = (1LL*result*256 + str[i])%prim;
			{
				xorVal = str[i];
				result ^= xorVal;
				result *= primescu;
			}
			return result;
		}
		
		unsigned int hashFunction1(unsigned int x)
        {
			return (1LL*a1*x + b1)%size;
        }
          
        unsigned int hashFunction2(unsigned int x)
        {
			return (1LL*a2*x + b2)%size;
        }
         
        unsigned int hash(unsigned int x)
        {
            if (H1[hashFunction1(x)]==x || H2[hashFunction2(x)]==x)
                return -1;	//se afla deja in hash
            unsigned int aux, val1, val2, i, old=x;
            bool inPlace = 0;
            for (i=0; !inPlace; ++i)
            {
                if (i && x==old)
                    return 0;	//ciclu
                val1=hashFunction1(x); val2=hashFunction2(x);
                if (H1[val1] == 0)
                {
                    H1[val1] = x;
                    inPlace = 1;
                }
                else if (H2[val2] == 0)
                {
                    H2[val2] = x;
                    inPlace = 1;
                }
                else
                {
                    aux = H1[val1];
                    H1[val1]=x; x=aux;
                    val2 = hashFunction2(x);
                    if (H2[val2] == 0)
                    {
                        H2[val2] = x;
                        inPlace = 1;
                    }
                    else
                    {
                        aux = H2[val2];
                        H2[val2]=x; x=aux;
                    }
                }
            }
            return 1;	//adaugat cu succes
        }
		
    public:
        Cuckoo(unsigned int SIZE)
        {
            srand(time(NULL));
            size = SIZE;
            H1 = (unsigned int*)calloc(size, sizeof(unsigned int));
            H2 = (unsigned int*)calloc(size, sizeof(unsigned int));
            a1=rand()%size; a2=rand()%size;
            b1=rand()%size; b2=rand()%size;
        }
		
		Cuckoo()
		{
			srand(time(NULL));
			size = rand()%250000 + 750001;
		    H1 = (unsigned int*)calloc(size, sizeof(unsigned int));
            H2 = (unsigned int*)calloc(size, sizeof(unsigned int));
            a1=rand()%size; a2=rand()%size;
            b1=rand()%size; b2=rand()%size;
		}
		
		//Adaugare:
        Cuckoo &operator <(type x)
        {
			unsigned int val = parse(x);
			unsigned int canInsert = hash(val);
			//Ciclu => rehash:
            if (!canInsert)
            {
                unsigned int *H1_temp = (unsigned int*)malloc(size*sizeof(unsigned int));
                memcpy(H1_temp, H1, size*sizeof(unsigned int));
                unsigned int *H2_temp = (unsigned int*)malloc(size*sizeof(unsigned int));
                memcpy(H2_temp, H2, size*sizeof(unsigned int));
                 
                while (!canInsert)
                {
                    a1=rand()%size; a2=rand()%size;
                    b1=rand()%size; b2=rand()%size;
                    free(H1); free(H2);
                    H1 = (unsigned int*)calloc(size, sizeof(unsigned int));
                    H2 = (unsigned int*)calloc(size, sizeof(unsigned int));
                     
                    canInsert = 1;
                    for (unsigned int i=0; i<size && canInsert==1; ++i)
                    {
                        if (H1_temp[i])
                            canInsert = hash(H1_temp[i]);
                        if (canInsert==1 && H2_temp[i])
                            canInsert = hash(H2_temp[i]);
                    }
                }

                free(H1_temp); 
				free(H2_temp);
            }
            return *this;
        }
         
		//unsigned interogare:
        Cuckoo &operator <=(type x)
        {
			unsigned int val = parse(x);
            printf("%d\n", H1[hashFunction1(val)]==val || H2[hashFunction2(val)]==val);
            return *this;
        }
		
		//Stergere:
        Cuckoo &operator >(type x)	
        {
			unsigned int val = parse(x);
            if (H1[hashFunction1(val)] == val)
                H1[hashFunction1(val)] = 0;
            else if (H2[hashFunction2(val)] == 0)
				H2[hashFunction2(val)] = 0;
            return *this;
        }
		
		//Inutil momentan:
		bool find(type x)
		{
			unsigned int val = parse(x);
			return (H1[hashFunction1(val)]==val || H2[hashFunction2(val)]==val);
		}
};
 
int main()
{    
	freopen("hashuri.in", "r", stdin);
    freopen("hashuri.out", "w", stdout);
    unsigned int n, c, x, i;
    Cuckoo<unsigned int> H;
    scanf("%d", &n);
    for (i=0; i<n; ++i)
    {
        scanf("%d%d", &c, &x);
        switch (c)
        {
            case 1: H <x; break;
            case 2: H >x; break;
            case 3: H <=x; break;
        }
    }
    return 0;
}