Cod sursa(job #905898)

Utilizator maritimCristian Lambru maritim Data 6 martie 2013 11:56:48
Problema Hashuri Scor 60
Compilator c Status done
Runda Arhiva educationala Marime 2.8 kb
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<assert.h>

#define M 2077771
#define H1 700127
#define H2 501131

inline int h1(int a,int hf1,int hf2)
{
    return (1LL*hf1*a+hf2)%M;
}

inline int h2(int a,int hf1,int hf2)
{
    return (1LL*hf2*a+hf1)%M;
}

inline void initializare(int *p)
{
    int i;

    for(i=0;i<M;i++)
        *(p+i) = 0;
}

inline int exist(int *p,int x,int hf1,int hf2)
{
    if(*(p+h1(x,hf1,hf2)) == x || *(p+h2(x,hf1,hf2)) == x)
        return 1;
    return 0;
}

inline int reordonate(int *p,int x,int hf1,int hf2,int logn)
{
    int hash2 = h2(x,hf1,hf2),y;

    if(!logn)
        return 0;

    if(*(p+hash2) != 0)
    {
        y = *(p+hash2);
        *(p+hash2) = x;
        return reordonate(p,y,hf1,hf2,logn>>1);
    }
    else
        *(p+hash2) = x;

    return 1;
}

inline int add(int *p,int x,int hf1,int hf2,int logn)
{
    if(exist(p,x,hf1,hf2))
        return 1;

    int hash1 = h1(x,hf1,hf2),y;

    if(*(p+hash1) != 0)
    {
        y = *(p+hash1);
        *(p+hash1) = x;
        return reordonate(p,y,hf1,hf2,logn);
    }
    else
        *(p+hash1) = x;

    return 1;
}

inline void sterge(int *p,int x,int hf1,int hf2)
{
    int hash1 = h1(x,hf1,hf2),hash2 = h2(x,hf1,hf2);

    if(*(p+hash1) == x)
        *(p+hash1) = 0;
    else if(*(p+hash2) == x)
        *(p+hash2) = 0;
}

inline void takefunctions(int *hf1,int *hf2)
{
    *hf1 = 50000 + rand()%100000;
    *hf2 = 70000 + rand()%100000;
}

inline void copiere(int *p,int *q)
{
    int i;

    for(i=0;i<M;i++)
        *(p+i) = *(q+i);

}

inline void rehash(int *p,int *q,int hf1,int hf2)
{
    int i, logn;

    while (1)
    {
        initializare(q);

        for (i=0, logn = 0 ; i<M ; i++)
            if(*(p+i))
                if(!add(q,*(p+i),hf1,hf2,++logn))
                    break;
    
        return ;
    }
}

void main()
{
    FILE *f = fopen("hashuri.in","r");
    FILE *g = fopen("hashuri.out","w");
    int *p,*q;
    int N,op,a;
    int hf1 = H1,hf2 = H2; 
    
    /*hf1 = hash function 1, hf2 = hash function 2*/

    srand(time(NULL));

    p = (int*)malloc(M*sizeof(int));

    initializare(p);

    int i,aux;

    fscanf(f,"%d",&N);
    for(i=1;i<=N;i++)
    {
        fscanf(f,"%d %d",&op,&a);
        switch(op)
        {
            case 1 : {
                        while(!add(p,a,hf1,hf2,N))
                        {
                            assert(1 == 0);
                            takefunctions(&hf1,&hf2);
                            rehash(p,q,hf1,hf2);
                            copiere(p,q);
                        }
                     }
                break;
            case 2 : sterge(p,a,hf1,hf2);
                break;
            case 3 : fprintf(g,"%d\n",exist(p,a,hf1,hf2));
        }
    }

    fclose(f);
    fclose(g);

//    for(i=0;i<M;i++)
//        printf("%d\n",*(p+i));
}