Cod sursa(job #859232)

Utilizator GagosGagos Radu Vasile Gagos Data 19 ianuarie 2013 21:33:49
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.51 kb
#include <cstdio>
#include <cstdlib>

#define MAX 666013

struct Node {
  int value;
  Node* next;

  Node() : value(0), next(NULL) { }
  Node(int value) : value(value), next(NULL) { }
  Node(int value, Node* next) : value(value), next(next) { }
};

class Hash {
public:
  Hash();

  void add(int value);
  void remove(int value);
  int exists(int value);

private:
  int count;
  int dim;
  Node** hash;

  void init_hash(int size);
  void rehash();
};

Hash::Hash() {
  this->count = 0;
  
  init_hash(11);
}

void Hash::add(int value) {
  if (this->count > 0.75 * this->dim) {
    rehash();
  }

  int index = value % this->dim;
  Node* node = new Node(value, this->hash[index]);

  this->hash[index] = node;
  this->count += 1;
}

int Hash::exists(int value) {
  int index = value % this->dim;

  for (Node* node = this->hash[index]; node != NULL; node = node->next) {
    if (node->value == value) {
      return 1;
    }
  }

  return 0;
}

void Hash::remove(int value) {
  int index = value % this->dim;
  Node* node = this->hash[index];
  Node* prev = node;

  if (this->count == 0 || node == NULL) {
    return;
  } 
  
  if (node->value == value) {
    this->hash[index] = this->hash[index]->next;
    this->count -= 1;

    delete node;

    return;
  }

  for (prev = node, node = node->next; node != NULL; prev = node, node = node->next) {
    if (node->value == value) {
      prev->next = node->next;
      this->count -= 1;

      delete node;

      return;
    }
  }
}

void Hash::init_hash(int size) {
  this->dim = size;
  this->hash = new Node*[this->dim];

  for (int i = 0; i < this->dim; ++i) {
    this->hash[i] = NULL;
  }
}

void Hash::rehash() {
  int old_dim = this->dim;
  int new_dim = (old_dim << 1) | 1;
  Node** old_hash = this->hash;
  
  init_hash((new_dim + MAX - abs(MAX - new_dim)) >> 1);
  
  for (int i = 0; i < old_dim; ++i) {
    for (Node* node = old_hash[i]; node != NULL; node = node->next) {
      add(node->value);
    }
  }

  delete old_hash;
}

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

  int n;
  Hash* hash = new Hash();

  scanf("%d", &n);

  while (n--) {
    int op, val;

    scanf("%d %d", &op, &val);

    if (op == 1) {
      hash->add(val);
    } else if (op == 2) {
      hash->remove(val);
    } else if (op == 3) {
      printf("%d\n", hash->exists(val));
    }
  }

  delete hash;

  fcloseall();

  return 0;
}