Cod sursa(job #708580)

Utilizator katakunaCazacu Alexandru katakuna Data 6 martie 2012 22:30:41
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.99 kb
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <ctime>
using namespace std;

#define LL (long long)

class cockooHash {

	int tableSize;
    int maxSteps;

	// h (x) = ((a * x + b) % prime) % tableSize)
	int a1, b1;
	int a2, b2;
	int prime;

	int *T1, *T2;
	bool *set1, *set2;

	void getHashFunction (int &a, int &b) {
		a = rand () % tableSize;
		b = rand () % tableSize;
	}

	int h1 (int key) {
		return ((LL this->a1 * LL key + LL this->b1) % LL this->prime ) % LL tableSize;
	}

	int h2 (int key) {
		return ((LL this->a2 * LL key + LL this->b2) % LL this->prime ) % LL tableSize;
	}

	void rehash () {

		getHashFunction (this->a1, this->b1);
		getHashFunction (this->a2, this->b2);

	}

	public:
	cockooHash (int tableSize) {

		this->tableSize = tableSize;
        maxSteps = (int) log2 (tableSize);

		this->prime = 1000000009;

		this->T1 = new int [tableSize];
		this->T2 = new int [tableSize];

		this->set1 = new bool[tableSize];
		this->set2 = new bool[tableSize];

		memset (this->T1, 0, sizeof (this->T1));
		memset (this->T2, 0, sizeof (this->T2));

		memset (this->set1, 0, sizeof (this->set1));
		memset (this->set2, 0, sizeof (this->set2));

		getHashFunction (this->a1, this->b2);
		getHashFunction (this->a2, this->b2);
	}

	bool find (int key) {

        if ( this->T1[ this->h1 (key) ] == key && this->set1[ this->h1 (key) ] == true) return true;
		if ( this->T2[ this->h2 (key) ] == key && this->set2[ this->h2 (key) ] == true) return true;

		return false;
	}

	bool erase (int key) {

		if (this->T1[ this->h1(key) ] == key && this->set1 [ this->h1(key) ]) {
			this->set1[ this->h1 (key) ] = 0;
			return true;
		}

		if (this->T2[ this->h2(key) ] == key && this->set2[ this->h2(key) ]) {
			this->set2[ this->h2 (key) ] = 0;
			return true;
		}

		return false;
	}

	bool insert (int key) {

		int x, y;
		int steps = 0;

		x = key;
		if ( this->set1[ this->h1 (x) ] == 0 ) {
			this->T1[ this->h1 (x)] = x;
			this->set1[ this->h1 (x) ] = 1;
			return true;
		}

		while (steps < maxSteps) {

			steps+= 2;
		    if ( this->set2[ this->h2 (x) ] == 0 ) {
				this->set2[ this->h2 (x) ] = 1;
				this->T2[ this->h2 (x) ] = x;
				return true ;
			}

			y = this->T2[this->h2 (x)];
			this->T2[ this->h2(x) ] = x;
			x = y;

			if ( this->set1[ this->h1 (x) ] == 0 ) {
				this->set1[ this->h1 (x) ] = 1;
				this->T1[ this->h1 (x) ] = x;
				return true ;
			}

			y = this->T1[ this->h1 (x) ];
			this->T1[ this->h1 (x) ] = x;
			x = y;
		}

        printf ("rehashhh!!");
        return false;
	}

};


int main () {

    srand ( time (0) );

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

    cockooHash myHash (1500000);

    int T, tip, key;
    scanf ("%d", &T);
    for (; T; T--) {
        scanf ("%d %d", &tip, &key);
        if (tip == 1 && !myHash.find (key)) myHash.insert (key);
        if (tip == 2 && myHash.find (key)) myHash.erase (key);
        if (tip == 3) printf ("%d\n", (int) myHash.find (key));
    }

    return 0;
}