Cod sursa(job #917410)

Utilizator Preda_IleanaPreda Ileana-Andreea Preda_Ileana Data 17 martie 2013 20:35:47
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.33 kb
#include<iostream>
#include<stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

#define SIZE_T1    200
#define SIZE_T2    150
#define SRCH_COUNT 60
#define PRIME      479001599
#define MIN        -2146483646



class CuckooHash {

	public:
		CuckooHash();			
		CuckooHash(int srch_count, int size_t1, int size_t2);
		~CuckooHash();
		void insert(int value);
		int getValue(int value);
		void remove(int value);
		bool containsValue(int value);


	private:
		int hash_t1(int value);
		int hash_t2(int value);
		int internal_hash(int value, int table);
		void rehash();
		void initialize_tables();

		int *t1, *t2;
		int srch_count, size_t1, size_t2;
		int a[2], b[2];
		

};


CuckooHash::CuckooHash() {
	srch_count = SRCH_COUNT;
	size_t1 = SIZE_T1;
	size_t2 = SIZE_T2;

	initialize_tables();
}

CuckooHash::CuckooHash(int srch_count, int size_t1, int size_t2) {
	this->srch_count = srch_count;						
	this->size_t1 = size_t1;
	this->size_t2 = size_t2;

	initialize_tables();
}

CuckooHash::~CuckooHash() {
	delete[] t1;
	delete[] t2;
}

void CuckooHash::insert(int value) {
	if(t1[hash_t1(value)] == MIN) {
		t1[hash_t1(value)] = value;					
		return;
	}
	if(t2[hash_t2(value)] == MIN) {
		t2[hash_t2(value)] = value;
		return;
	}

	int poz = hash_t1(value);
	
	for(int i = 0; i < srch_count; i++) {
		if(t1[poz] == MIN) {
			t1[poz] = value;
			return;
		}

		t1[poz] ^= value;
		value ^= t1[poz];
		t1[poz] ^= value;		
		
		poz = hash_t2(value);
		if(t2[poz] == MIN) {
			t2[poz] = value;
			return;
		}

		t2[poz] ^= value;
		value ^= t2[poz];
		t2[poz] ^= value;

		poz = hash_t1(value);
	}

	rehash();
}

int CuckooHash::getValue(int value) {
	if(t1[hash_t1(value)] == value)
		return t1[hash_t1(value)];
	if(t2[hash_t2(value)] == value)
		return t2[hash_t2(value)];
	return MIN;
}

void CuckooHash::remove(int value) {
	if(t1[hash_t1(value)] == value)
		t1[hash_t1(value)] = MIN;
	if(t2[hash_t2(value)] == value)
		t2[hash_t2(value)] = MIN;
}

bool CuckooHash::containsValue(int value) {
	return t1[hash_t1(value)] == value ||
		t2[hash_t2(value)] == value;
}

int CuckooHash::hash_t1(int value) {
	
	return (internal_hash(value, 0) % size_t1);
}

int CuckooHash::hash_t2(int value) {
	return (internal_hash(value, 1) % size_t2);
}

int CuckooHash::internal_hash(int value, int table) {
	return (a[table] * value + b[table]) % PRIME;
}

void CuckooHash::rehash() {

	int *bk1 = t1,
		*bk2 = t2;

	size_t1 *= 2;
	size_t2 *= 2;

	initialize_tables();

	for(int i = 0; i < size_t1 / 2; i++)
		if(bk1[i] != MIN)
			insert(bk1[i]);

	for(int i = 0; i < size_t2 / 2; i++)
		if(bk2[i] != MIN)
			insert(bk2[i]);

	delete[] bk1;
	delete[] bk2;

}

void CuckooHash::initialize_tables() {

	t1 = new int[size_t1];

	for(int i = 0; i < size_t1; i++)
		t1[i] = MIN;

	t2 = new int[size_t2];

	for(int i = 0; i < size_t2; i++)
		t2[i] = MIN;
	
	srand(time(NULL));
	a[0] = rand();
	a[1] = rand();
	b[0] = rand();
	b[1] = rand();
}



int main() {
	

	freopen("hashuri.in","r",stdin);
	freopen("hashuri.out","w",stdout);

	CuckooHash x;
	int N;
	scanf("%d",&N);
	
	for(int i = 0; i < N; i++){;
		int op, value;	
		scanf("%d%d",&op,&value);
		
		if(op == 1){
			if(!x.containsValue(value))
				x.insert(value);
		}
		
		if(op == 2){
			if(x.containsValue(value))
				x.remove(value);
		}
		
		if(op == 3)
			printf("%d\n",x.containsValue(value));
		
	}
	return 0;
}