Cod sursa(job #714413)

Utilizator AnaTudorTudor Ana Maria Mihaela AnaTudor Data 15 martie 2012 18:52:05
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ll long long
using namespace std;

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

class cuckooHash {
	private:
		int *T1, *T2;
		bool *use1, *use2;
		int upper_bound, step, table_size;
		int a1, a2, b1, b2;
		int p;
	public:
		cuckooHash( int size );
		void insert( int key );
		void erase( int key );
		int search( int key, int &sw );
		int hash1( int key );
		int hash2( int key );
		void swap( int &a, int &b );
} ;

cuckooHash::cuckooHash( int size ) {
	table_size = size;
	T1 = new int[ size+10 ];
	T2 = new int[ size+10 ];
	use1 = new bool[ size+10];
	use2 = new bool[ size+10 ];
	a1 = 1 + rand() % size;
	b1 = rand() % size;
	a2 = 1 + rand() % size;
	b2 = rand() % size;
	p = 1000000009;
	upper_bound = (int) log2(table_size);
	step = 0;
	int i;
	for( i = 0; i < size; ++i )
		T1[ i ] = T2[ i ] = 0,
		use1[ i ] = use2[ i ] = 0;
}

int cuckooHash::hash1( int key ) {
	return ( ( ll ) ( a1 * ( ll )key + b1 ) % p ) % ( ll ) table_size;
}

int cuckooHash::hash2( int key ) {
	return ( ( ll )( a2 * ( ll )key + b2 ) % p ) % ( ll )table_size;
}

void cuckooHash::swap( int &a, int &b ) {
	int aux = a;
	a = b; b = aux;
}

int cuckooHash::search( int key, int &sw ) {
	int  position = hash1( key );
	if( T1[ position ] == key && use1[ position ] == true ) {
		sw = 1;
		return position;
	}
	position = hash2( key );
	if( T2[ position ] == key && use2[ position ] == true ) {
		sw = -1;
		return position;
	}
	return -1;
}

void cuckooHash::insert( int key ) {
	int value = hash1( key ), aux, sw = 1;
	if( search( key, sw ) != -1 )
		return;
	if( T1[ value ] == 0 ) {
		T1[ value ] = key;
		use1[ value ] = 1;
		return;
	}
    step=0;sw=1;
	aux = T1[ value ];
	T1[ value ] = key;
	while( aux != 0 && step <= upper_bound ) {
		if( sw == 1 ) {
			value = hash2( aux );
			swap( aux, T2[ value ] );
			use2[ value ] = 1;
		}
		else {
			value = hash1( aux );
			swap( aux, T1[ value ] );
			use1[ value ] = 1;
		}
		step ++;
		sw *= -1;
	}
}


void cuckooHash::erase( int key ) {
	int  sw, position = search( key, sw );
	if( position == -1 )
		return;
	if( sw == 1 )
		use1[ position ] = 0;
	else
		use2[ position ] = 0;
}

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