Cod sursa(job #712074)

Utilizator jeanFMI - Petcu Ion Cristian jean Data 13 martie 2012 00:19:43
Problema Hashuri Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define Nmax 1000010u
//#define P 1000000009u
#define m 17u
#define M 1<<m
#define w 32u

unsigned int H1[M+5][4], H2[M+5][4], S[Nmax], op, T, X, hashuri ;
unsigned long long A1, A2, B1, B2 ;
//unsigned long long A,B ;

int search ( unsigned int X ) 
{
	int i ; 
	long long h1, h2 ; 
	
	//h1 = ( (A1 * X + B1) % P ) % M ; 
	//h2 = ( (A2 * X + B2) % P ) % M ;
	h1 = ( ( A1 * X + B1 ) & ( (1<<w) - 1 ) )>>(w-m);
	h2 = ( ( A2 * X + B2 ) & ( (1<<w) - 1 ) )>>(w-m);

	for( i = 0 ; i < 4 ; i++ )
		if( H1[h1][i] == X || H2[h2][i] == X ) 
			return 1 ;
	
	return 0 ;
}
	
void make_hash() ;

void insert ( unsigned int X ) 
{
	int i ;
	unsigned long long h1, h2 ; 
	
	//h1 = ( (A1 * X + B1) % P ) % M ; 
	//h2 = ( (A2 * X + B2) % P ) % M ;

	h1 = ( ( A1 * X + B1 ) & ( (1<<w) - 1 ) )>>(w-m);
	h2 = ( ( A2 * X + B2 ) & ( (1<<w) - 1 ) )>>(w-m);

	for( i = 0 ; i < 4 ; i++ )
		if( !H1[h1][i] ) 
		{
			H1[h1][i] = X ; 
			return ;
		}
		else if( !H2[h2][i] ) 
		{
			H2[h2][i] = X ;
			return ;
		}

	make_hash();
}

void erase ( unsigned int X ) 
{
	int i,j ;
	unsigned long long h1, h2 ; 
	
	//h1 = ( (A1 * X + B1) % P ) % M ; 
	//h2 = ( (A2 * X + B2) % P ) % M ;
	h1 = ( ( A1 * X + B1 ) & ( (1<<w) - 1 ) )>>(w-m);
	h2 = ( ( A2 * X + B2 ) & ( (1<<w) - 1 ) )>>(w-m);
	
	for( i = 0 ; i < 4 ; i++ )
		if( H1[h1][i] == X ) 
		{
			for( j = i ; j < 3 ; j++ )
				H1[h1][j] = H1[h1][j+1];
			H1[h1][j] = 0 ;  
		}
		else 
		if( H2[h2][i] == X ) 
		{
			for( j = i ; j < 3 ; j++ )
				H2[h2][j] = H2[h2][j+1];
			H2[h2][j] = 0 ;
		}
}

void make_hash () 
{
	int i,j;
	
	int N = 0 ;
	
	for( i = 0 ; i < M ; i++ )
		for( j = 0 ; j < 4 ; H1[i][j] = H2[i][j] = 0 , j++ )
			if( H1[i][j] ) 
				S[++N] = H1[i][j] ;
	
	//A1 = rand() % P ;
	//A2 = rand() % P ;
	//B1 = rand() % P ;
	//B2 = rand() % P ;
	A1 = rand() % ((1<<w)-1) ;  if( !(A1&1) ) A1++;
	A2 = rand() % ((1<<w)-1) ;  if( !(A2&1) ) A2++;
	B1 = (1<<(w>>1)) + rand() % (1<<(w>>1)) ;
	B2 = (1<<(w>>1)) + rand() % (1<<(w>>1)) ;
	
	for( i = 1 ; i <= N ; i++ )
		insert( S[i] ) ;
	
	hashuri++;
}
int main () 
{
	clock_t start = clock() ; 
	
	srand(time(0));
	
	freopen("hashuri.in","r",stdin);
	freopen("hashuri.out","w",stdout);
	
	scanf("%d",&T);
	
	make_hash() ; 
	
	while( T-- ) 
	{
		scanf("%u %u",&op,&X) ; 
		
		switch(op)
		{
		case 1:
			insert(X); break ; 
		case 2:
			erase(X); break ; 
		case 3:
			printf("%d\n",search(X)); break ; 
		}
	}
	
	clock_t finish = clock() ;
	double time = (double)(finish-start)/CLOCKS_PER_SEC;
	
	//printf("\n%d re-hash\n\n%lf\n",hashuri-1,time);
	
	return 0 ;
}