Pagini recente » Cod sursa (job #2258271) | Cod sursa (job #677533) | Cod sursa (job #2596084) | Cod sursa (job #2189891) | Cod sursa (job #712069)
Cod sursa(job #712069)
#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;
int nrInsert;
int fact;
// 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;
}
void resize (int tableSize) {
if (tableSize < this->tableSize) {
this->tableSize = tableSize;
this->maxSteps = (int) log2(tableSize);
rehash ();
this->T1 = (int *)realloc (this->T1, tableSize * sizeof (int));
this->T2 = (int *)realloc (this->T2, tableSize * sizeof (int));
this->set1 = (bool *)realloc (this->set1, tableSize);
this->set2 = (bool *)realloc (this->set2, tableSize);
}
else {
this->T1 = (int *)realloc (this->T1, tableSize * sizeof (int));
this->T2 = (int *)realloc (this->T2, tableSize * sizeof (int));
this->set1 = (bool *)realloc (this->set1, tableSize);
this->set2 = (bool *)realloc (this->set2, tableSize);
memset (this->set1 + this->tableSize, 0, this->tableSize);
memset (this->set2 + this->tableSize, 0, this->tableSize);
this->tableSize = tableSize;
this->maxSteps = (int) log2(tableSize);
this->rehash ();
}
}
void rehash () {
getHashFunction (this->a1, this->b1);
getHashFunction (this->a2, this->b2);
for (int i = 0; i < this->tableSize; ++i) {
if (this->set1[i] == true && i != this->h1 ( this->T1[i] )) {
this->set1[i] = 0;
this->nrInsert--;
this->insert ( this->T1[i] );
}
if (this->set2[i] == true && i != this->h2 ( this->T2[i] )) {
this->set2[i] = 0;
this->nrInsert--;
this->insert ( this->T2[i] );
}
}
}
public:
cockooHash () {
this->fact = 2;
this->tableSize = (1 << this->fact);
maxSteps = (int) log2 (tableSize);
this->prime = 1000000009;
this->nrInsert = 0;
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);
}
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;
}
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) {
int success = false;
if (this->T1[ this->h1(key) ] == key && this->set1 [ this->h1(key) ]) {
this->set1[ this->h1 (key) ] = 0;
success = true;
}
if (this->T2[ this->h2(key) ] == key && this->set2[ this->h2(key) ]) {
this->set2[ this->h2 (key) ] = 0;
success = true;
}
if (success == true) {
this->nrInsert--;
if ( (this->nrInsert << this->fact) < this->tableSize >> 1)
this->resize (this->tableSize >> 1);
}
return success;
}
void insert (int key) {
int x, y;
int steps = 0;
bool success = false;
x = key;
if ( this->set1[ this->h1 (x) ] == 0 ) {
this->T1[ this->h1 (x)] = x;
this->set1[ this->h1 (x) ] = 1;
success = true;
}
while (success == false && steps < maxSteps) {
steps+= 2;
if ( this->set2[ this->h2 (x) ] == 0 ) {
this->set2[ this->h2 (x) ] = 1;
this->T2[ this->h2 (x) ] = x;
success = true;
break;
}
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;
success = true;
break;
}
y = this->T1[ this->h1 (x) ];
this->T1[ this->h1 (x) ] = x;
x = y;
}
if (success == true) {
this->nrInsert++;
if ( (this->nrInsert << this->fact) > this->tableSize)
this->resize (this->tableSize << 1);
return ;
}
this->rehash ();
this->insert (key);
}
};
int main () {
freopen ("hashuri.in", "r", stdin);
freopen ("hashuri.out", "w", stdout);
//printf ("%d\n", time (0));
srand ( time (0) );
cockooHash myHash;
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;
}