#include <stdlib.h>
const int _linear_hash_capacity[] = {
0,
3,
7,
13,
29,
53,
97,
193,
389,
769,
1543,
3079,
6151,
12289,
24593,
49157,
98317,
196613,
393241,
786433,
1572869,
3145739,
6291469,
12582917,
25165843,
50331653,
100663319,
201326611,
402653189,
805306457,
1610612741,
};
typedef struct{
void *key, *val;
} _linear_hash_node_t;
typedef struct{
_linear_hash_node_t* hash;
int* deleted_element;
int size, cap;
int (*compare_key)(void*, void*);
int (*linear_hash_function)(void*);
int (*probing_increment)(int);
} _linear_hash_t;
///PRIVATE FUNCTIONS
int _linear_hash_linear(int);
int _linear_hash_quadratic(int);
void _linear_hash_calibration(_linear_hash_t*);
int _linear_hash_keep_going(_linear_hash_t*, _linear_hash_node_t, void*, int);
_linear_hash_node_t* _linear_hash_supposed_position(_linear_hash_t*, void*, int);
_linear_hash_node_t* _linear_hash_find(_linear_hash_t*, void*);
///PUBLIC FUNCTIONS
void* linear_hash_new(int (*)(void*, void*), int (*)(void*), int);
void linear_hash_clear(_linear_hash_t*);
void linear_hash_delete(_linear_hash_t*);
int linear_hash_contains(_linear_hash_t*, void*);
int linear_hash_is_empty(_linear_hash_t*);
int linear_hash_get_size(_linear_hash_t*);
int linear_hash_get_capacity(_linear_hash_t*);
void linear_hash_insert(_linear_hash_t*, void*, void*);
void linear_hash_erase(_linear_hash_t*, void*);
void linear_hash_iterate(_linear_hash_t*, void (*)(void*, void*));
///PRIVATE FUNCTIONS
int _linear_hash_linear(int i){
return 1;
}
int _linear_hash_quadratic(int i){
return (i << 1) + 1;
}
void _linear_hash_calibration(_linear_hash_t* hash){
int capacity, oldCapacity;
oldCapacity = linear_hash_get_capacity(hash);
hash -> cap++;
capacity = linear_hash_get_capacity(hash);
_linear_hash_node_t* area = hash -> hash;
hash -> hash = malloc(capacity * sizeof(_linear_hash_node_t));
linear_hash_clear(hash);
int i;
for (i = 0 ; i < oldCapacity ; i++)
if (area[i].key != NULL && area[i].key != hash -> deleted_element)
linear_hash_insert(hash, area[i].key, area[i].val);
free(area);
}
int _linear_hash_keep_going(_linear_hash_t* hash, _linear_hash_node_t node, void* key, int insertORfind){
if (node.key == NULL)
return 0;
if (node.key == hash -> deleted_element)
return insertORfind;
return hash -> compare_key(node.key, key) != 0;
}
_linear_hash_node_t* _linear_hash_supposed_position(_linear_hash_t* hash, void* key, int insertORfind){
int cap = linear_hash_get_capacity(hash);
int poz = hash -> linear_hash_function(key) % cap, i = 0;
while (_linear_hash_keep_going(hash, hash -> hash[poz], key, insertORfind))
poz = (poz + hash -> probing_increment(i++)) % cap;
return (hash -> hash) + poz;
}
_linear_hash_node_t* _linear_hash_find(_linear_hash_t* hash, void* key){
if (hash -> size == 0)
return NULL;
_linear_hash_node_t* poz = _linear_hash_supposed_position(hash, key, 1);
return (poz -> key != NULL && poz -> key != hash -> deleted_element) ? poz : NULL;
}
///PUBLIC FUNCTIONS
void* linear_hash_new(int (*compare_key)(void*, void*), int (*linear_hash_function)(void*), int linearORquadratic_probing){
_linear_hash_t* H = malloc( sizeof(_linear_hash_t) );
H -> hash = NULL;
H -> size = 0;
H -> cap = 0;
H -> compare_key = compare_key;
H -> linear_hash_function = linear_hash_function;
if (linearORquadratic_probing)
H -> probing_increment = _linear_hash_quadratic;
else
H -> probing_increment = _linear_hash_linear;
H -> deleted_element = malloc( sizeof(int) );
return H;
}
void linear_hash_clear(_linear_hash_t* hash){
memset(hash -> hash, 0, linear_hash_get_capacity(hash) * sizeof(_linear_hash_node_t));
hash -> size = 0;
}
void linear_hash_delete(_linear_hash_t* hash){
free(hash -> hash);
free(hash -> deleted_element);
free(hash);
}
int linear_hash_contains(_linear_hash_t* hash, void* key){
return _linear_hash_find(hash, key) != NULL;
}
int linear_hash_is_empty(_linear_hash_t* hash){
return hash -> size == 0;
}
int linear_hash_get_size(_linear_hash_t* hash){
return hash -> size;
}
int linear_hash_get_capacity(_linear_hash_t* hash){
return _linear_hash_capacity[ hash -> cap ];
}
void linear_hash_insert(_linear_hash_t* hash, void* key, void* val){
_linear_hash_node_t* poz = _linear_hash_find(hash, key);
if (poz != NULL && poz -> key != hash -> deleted_element){
free(poz -> val);
poz -> val = val;
return;
}
if ( (hash -> size << 1) >= linear_hash_get_capacity(hash))
_linear_hash_calibration(hash);
hash -> size++;
poz = _linear_hash_supposed_position(hash, key, 0);
poz -> key = key;
poz -> val = val;
}
void linear_hash_erase(_linear_hash_t* hash, void* key){
_linear_hash_node_t* poz = _linear_hash_find(hash, key);
if (poz == NULL)
return;
hash -> size--;
free(poz -> key);
free(poz -> val);
poz -> key = poz -> val = hash -> deleted_element;
}
void linear_hash_iterate(_linear_hash_t* hash, void (*iterate)(void*, void*)){
int capacity = _linear_hash_capacity[ hash -> cap ], i;
for (i = 0 ; i < capacity ; i++)
if (hash -> hash[i].key != NULL && hash -> hash[i].val != hash -> deleted_element)
iterate(hash -> hash[i].key, hash -> hash[i].val);
}
///ACTUAL CODE
int compara(void* a, void *b){
return (*(int*)a) != (*(int*)b);
}
int hashFunction(void* a){
return *(int*)a;
}
int* fint(int x){
int* poz = malloc(sizeof(int));
*poz = x;
return poz;
}
char* sth(){
return malloc(sizeof(char));
}
#include <stdio.h>
int main(){
void* hash = linear_hash_new(compara, hashFunction, 0);
FILE* fin = fopen("hashuri.in", "r");
FILE* fout = fopen("hashuri.out", "w");
int times, tip, x, *stn;
fscanf(fin, "%d", ×);
while (times--){
fscanf(fin, "%d%d", &tip, &x);
if (tip == 1)
linear_hash_insert(hash, fint(x), sth());
if (tip == 2){
stn = fint(x);
linear_hash_erase(hash, stn);
free(stn);
}
if (tip == 3){
stn = fint(x);
fprintf(fout, "%d\n", linear_hash_contains(hash, stn));
free(stn);
}
}
fclose(fin);
fclose(fout);
return 0;
}