Cod sursa(job #907508)

Utilizator IoannaPandele Ioana Ioanna Data 7 martie 2013 23:45:04
Problema Hashuri Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 3.71 kb
#include <fstream>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <cassert>

using namespace std;

class HashTable {
  private:
    int *h1;
    int *h2;
    int size;
    int prime;
    int a1,a2,b1,b2;

  public:

  HashTable(int);

  bool InsertElement(int&);
  bool DeleteElement(int&);
  int FindElement(int&);
  int HashFunction1(int&);
  int HashFunction2(int&);
  bool GenerateFunctions();
  bool Rehash();
  HashTable Pointer();

  ~HashTable();
};

HashTable::HashTable(int sz){
  size = sz;
  h1 = new int[sz];
  h2 = new int[sz];
  memset(h1,0,size*sizeof(int));
  memset(h2,0,size*sizeof(int));
  prime=1000000009;
  GenerateFunctions();
}

HashTable::~HashTable() {
  delete[] h1;
  delete[] h2;
}

HashTable HashTable::Pointer() {
  return *this;
}

int HashTable::HashFunction1(int &value) {
  return (((long long)a1 * value + b1)%prime)%size;
}

int HashTable::HashFunction2(int &value) {
  return (((long long)a2 * value + b2)%prime)%size;
}

int HashTable::FindElement(int &value) {
  int location1,location2;
  location1 = HashFunction1(value);
  location2 = HashFunction2(value);
  if (h1[location1] == value){
    return location1;
  } else if (h2[location2]){
    return location2;
  }
  return -1;
}

bool HashTable::DeleteElement(int &value) {
  int location = FindElement(value);
  if (location == -1) return false;
  if (h1[location] == value){
    h1[location] = 0;
    return true;
  }
  h2[location] = 0;
  return true;
}

bool HashTable::GenerateFunctions(){
  a1 = rand() % size;
  a2 = rand() % size;
  b1 = rand() % size;
  b2 = rand() % size;
  return true;
}

bool HashTable::InsertElement(int &value) {
  int temporary_value = value;
  int location;
  int aux;
  int choose_table = 1;
  do {
    if (choose_table == 1) {
      location = HashFunction1(temporary_value);
      if (h1[location]) {
        aux = h1[location];
        h1[location] = temporary_value;
        temporary_value = aux;
      } else {
        h1[location] = temporary_value;
        return true;
      }
    } else {
      location = HashFunction2(temporary_value);
      if (h2[location]) {
        aux = h2[location];
        h2[location] = temporary_value;
        temporary_value = aux;
      } else {
        h2[location] = temporary_value;
        return true;
      }
    }
    choose_table = -choose_table;
  }
  while (temporary_value !=value || choose_table == -1);
  return false;
}

bool HashTable::Rehash() {
  HashTable temp(1000000);
  for (int i = 0; i<size; ++i) {
    if (h1[i]) {
      if (!temp.InsertElement(h1[i]))
        return false;
    }
    if (h2[i]) {
      if (!temp.InsertElement(h2[i]))
        return false;
    }
  }
  *this = temp.Pointer();
  return true;
}

void solve() {

  HashTable table(1000000);
  ifstream in("hashuri.in");
  ofstream out("hashuri.out");

  srand(time(NULL));

  int number_of_operations;
  int operation,element;

  in>>number_of_operations;
  for (int i = 1;i <= number_of_operations; ++i) {
    in>>operation>>element;
    switch (operation) {
      case 1: {
          if (table.FindElement(element) == -1) {
            while (!table.InsertElement(element)) {
              while (!table.Rehash()){}
            }
          }
          break;}
      case 2:{
          if (table.FindElement(element) != -1) table.DeleteElement(element);
          break;}
      case 3:{
          if (table.FindElement(element) != -1) {
            out<<"1\n";
          } else {
            out<<"0\n";
          }
          break;}
      default: {
        assert(false);
      }
    }
  }
}

int main() {
  solve();
  return 0;
}