Cod sursa(job #750416)

Utilizator irene_mFMI Irina Iancu irene_m Data 22 mai 2012 04:04:03
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.29 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LL long long
using namespace std;

const char infile[] = "hashuri.in", outfile[] = "hashuri.out";
const int MAX_N = 1000005;
int T, operation;

int key;

template <int table_size>
class random_function{
    public:
        int a, b, p;
        random_function(){
            a =  1 + rand() % table_size;
            b = rand() % table_size;
            p = 200 * MAX_N;
        }
};

template < class Type, int table_size >
class cuckooHash {
		Type *T;
		int upper_bound, step;
		random_function <table_size> f1, f2;
	public:
		cuckooHash( );
		int insert( Type );
		int erase( Type );
		LL search( Type, int  & );
		LL hash( random_function <table_size>, Type );
		int swap( Type &, Type & );
} ;

template < class Type, int table_size >
cuckooHash < Type, table_size > :: cuckooHash() {
	T = new Type[ 2 * table_size ];
	upper_bound = table_size / 2;
	step = 0;
	memset( T, sizeof( T ), 0 );
}

template < class Type, int table_size >
LL cuckooHash < Type, table_size > :: hash( random_function <table_size> f, Type key ) {
    LL fr, pt;
    pt = ( LL )key;
    fr = 1000 * ( key - pt );
	return ( ( LL )( f.a * ( LL )( pt + fr )+ f.b ) % f.p ) % ( LL )table_size;
}

template <>
LL cuckooHash < char[], MAX_N > :: hash( random_function <MAX_N> f, char key[] ) {
	unsigned LL h = 0;
	int n = strlen(key), i, c;
	for( i = 0; i < n; ++i, c = key[ i ] )
		h = c + ( h << 6 ) + ( h >> 16 ) - h;
	return ( ( LL )( f.a * h + f.b ) % f.p ) % ( LL )MAX_N;
}

template < class Type, int table_size >
int cuckooHash < Type, table_size > :: swap( Type &a, Type &b ) {
	Type aux = a; a = b; b = aux;
	return 1;
}
template < class Type, int table_size >
LL cuckooHash < Type, table_size > :: search( Type key, int &sw ) {
	LL  position = hash( f1, key );
	if( T[ position ] == key ) {
		sw = 1;
		return position;
	}
	position = hash( f2, key );
	if( T[ position + table_size ] == key ) {
		sw = -1;
		return position;
	}
	return -1;
}

template < class Type, int table_size >
int cuckooHash < Type, table_size > :: insert( Type key ) {
	LL value = hash( f1, key );
	Type aux = T[ value ];
	int sw;
	if( search( key, sw ) != -1 )
		return 1;
	if( T[ value ] == 0 ) {
		T[ value ] = key;
		return 1;
	}

	T[ value ] = key;
	for( sw = 1, step = 0; aux != 0 && step < upper_bound; ++step, sw*=-1 )
		if( sw == 1 ) {
			value = hash( f2, aux );
			swap( aux, T[ value + table_size ] );
		}
		else {
			value = hash( f1, aux );
			swap( aux, T[ value ] );
		}

	if( step >= upper_bound )
        return 0;
	return 1;
}

template < class Type, int table_size >
int cuckooHash < Type, table_size > :: erase( Type key ) {
	int  sw;
	LL position = search( key, sw );
	if( position == -1 )
		return 0;
	if( sw != 1 )   position += table_size;
    T[ position ] = 0;
	return 1;
}

int solve() {
	freopen( infile, "r", stdin );
	freopen( outfile, "w", stdout );
	scanf( "%d", &T );
	cuckooHash < int, MAX_N > O;
	for( ; T; T-- ) {
		scanf( "%d %d", &operation, &key );
		if( operation == 1 )
			if( !O.insert( key ) ){
                printf("Rehashing!");
                return 0;
			}
		if( operation == 2 )
			O.erase( key );
		if( operation == 3 )
			printf( "%d\n", O.search( key, operation ) == -1 ? 0 : 1 );
	}
	fclose( stdin );
	fclose( stdout );
	return 1;
}

int main(){
    while(!solve()) ;
    return 0;
}