Cod sursa(job #749757)

Utilizator DraStiKDragos Oprica DraStiK Data 18 mai 2012 17:22:11
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 5.68 kb
#include <vector>
#include <string>
#include <set>
#include <map>
#include <fstream>
using namespace std;

#define MAGIC 0.6180339887498948
#define PRIM 666013
#define OFFSET 1.5
#define DEL -1
#define NIL 0
#define SET 1

int get_prime (int N) {
  bool *tmp;
  int i,j,prime;

  tmp=new bool[N+1];
  for (i=0; i<=N; ++i)
    tmp[i]=0;

  prime=2;
  for (i=2; i<=N; ++i)
    if (!tmp[i]) {
      prime=i;

      for (j=i; j<=N; j+=i)
        tmp[j]=1;
    }
  delete[] tmp;

  return prime;
}

template <class myType>
class myHash {

  protected:
  myType *T;
  int *set;
  int size;

  public:
  myHash () {
    int i;

    this->size=get_prime ((int)(OFFSET*PRIM));
    this->T=new myType[this->size];
    this->set=new int[this->size];
    for (i=0; i<this->size; ++i)
      this->set[i]=0;
  }

  myHash (int size) {
    int i;

    this->size=get_prime ((int)(OFFSET*size));
    this->T=new myType[this->size];
    this->set=new int[this->size];
    for (i=0; i<this->size; ++i)
      this->set[i]=0;
  }

  virtual ~myHash () {

    delete[] T;
    delete[] set;
  }

  virtual int insert (myType)=0;
  virtual int erase (myType)=0;
  virtual int find (myType)=0;
};

template <class myType>
class myHashDouble : public myHash <myType> {
  using myHash <myType> :: T;
  using myHash <myType> :: set;
  using myHash <myType> :: size;

  inline int h1 (myType);
  inline int h2 (myType);

  inline int h (myType key,int poz) {

    return (this->h1 (key)+poz*this->h2 (key))%this->size;
  }

  public:
  myHashDouble () : myHash <myType> (PRIM) {}
  myHashDouble (int size) : myHash <myType> (size) {}

  inline int find (myType key) {
    int i,j;

    for (i=0; i<this->size; ++i) {

        j=this->h (key,i);
        if (this->T[j]==key && this->set[j]==SET)
          return j;

        if (this->set[j]==NIL)
          return -1;
    }

    return -1;
  }

  inline int insert (myType key) {
    int i,j,is;

    is=this->find (key);
    if (is>=0)
      return is;

    for (i=0; i<this->size; ++i) {

      j=this->h (key,i);
      if (this->set[j]==NIL || this->set[j]==DEL) {

        this->T[j]=key; this->set[j]=SET;
        return j;
      }
    }

    return -1;
  }

  inline int erase (myType key) {
    int i;

    i=this->find (key);
    if (i<0)
      return -1;

    this->set[i]=DEL;
    return i;
  }
};

template <class myType>
inline int myHashDouble <myType> :: h1 (myType key) {
  typename myType :: iterator it;
  int value;
  value=0;
  for (it=key.begin (); it!=key.end (); ++it)
    value=*it^(value<<4)^(value>>28);

  return value%this->size;
}

template <class myType>
inline int myHashDouble <myType> :: h2 (myType key) {
  typename myType :: iterator it;
  int value;

  value=0;
  for (it=key.begin (); it!=key.end (); ++it)
    value=*it^(value<<4)^(value>>28);

  return 1+value%(this->size-1);
}

template <>
inline int myHashDouble <int> :: h1 (int key) {

  return key%this->size;
}

inline double fract (double key) {

  return key-(int)key;
}

template <>
inline int myHashDouble <int> :: h2 (int key) {

  return 1+key%(this->size-1);
}

template <>
inline int myHashDouble <double> :: h1 (double key) {

  return (int)(fract (MAGIC*key)*this->size);
}

template <>
inline int myHashDouble <double> :: h2 (double key) {

  return 1+(int)(fract (MAGIC*key)*(this->size-1));
}

template <class myType>
class myHashLinear : public myHash <myType> {
  using myHash <myType> :: T;
  using myHash <myType> :: set;
  using myHash <myType> :: size;

  inline int h (myType);

  public:
  myHashLinear () : myHash <myType> (PRIM) {}
  myHashLinear (int size) : myHash <myType> (size) {}

  inline int find (myType key) {
    int i;

    for (i=h (key); i<this->size; ++i)
      if (this->set[i]==NIL)
        return -1;
      else if (this->T[i]==key && this->set[i]==SET)
        return i;

    for (i=h (key); i>=0; --i)
      if (this->set[i]==NIL)
        return -1;
      else if (this->T[i]==key && this->set[i]==SET)
        return i;

    return -1;
  }

  inline int insert (myType key) {
    int i;

    i=this->find (key);
    if (i>=0)
      return i;

    for (i=h (key); i<this->size; ++i)
      if (this->set[i]==NIL || this->set[i]==DEL) {

        this->T[i]=key; this->set[i]=SET;
        return i;
      }

    for (i=h (key); i>=0; --i)
      if (this->set[i]==NIL || this->set[i]==DEL) {


        this->T[i]=key; this->set[i]=SET;
        return i;
      }

    return -1;
  }

  inline int erase (myType key) {
    int i;

    i=this->find (key);
    if (i<0)
      return -1;

    this->set[i]=DEL;
    return i;
  }
};

template <class myType>
inline int myHashLinear <myType> :: h (myType key) {
  typename myType :: iterator it;
  int value;

  value=0;
  for (it=key.begin (); it!=key.end (); ++it)
    value=*it^(value<<4)^(value>>28);

  return value%this->size;
}

template <>
inline int myHashLinear <int> :: h (int key) {

  return key%this->size;
}

template <>
inline int myHashLinear <double> :: h (double key) {

  return (int)(fract (MAGIC*key)*this->size);
}

ifstream fin ("hashuri.in");
ofstream fout ("hashuri.out");

int main () {
  int N,i,op;
  int x;

  fin>>N;
  myHash <int> *HashTable;
  HashTable=new myHashDouble <int> (N);

  for (i=1; i<=N; ++i) {

    fin>>op>>x;

    if (op==1)
      HashTable->insert (x);

    if (op==2)
      HashTable->erase (x);

    if (op==3) {

      if (HashTable->find (x)>=0)
        fout<<"1\n";
      else
        fout<<"0\n";
    }
  }

  delete HashTable;

  return 0;
}