Cod sursa(job #715039)

Utilizator DraStiKDragos Oprica DraStiK Data 16 martie 2012 15:27:34
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.52 kb
#include <cassert>
#include <cstdio>
using namespace std;

#define MAGIC 0.618
#define OFFSET 1.25

#define DEL -1
#define SET 1
#define NIL 0

//Works with integers and doubles.

template <class _type> class hash_table {

  private:
  int hash_size;
  _type *T;
  int *F;

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

    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;
  }

  int h1 (_type key) {
    double fractional;

    fractional=(double)MAGIC*key;
    fractional-=(int)fractional;

    return (int)(fractional*this->hash_size);
  }

  int h2 (_type key) {
    double fractional;

    fractional=(double)MAGIC*key;
    fractional-=(int)fractional;

    return 1+(int)(fractional*(this->hash_size-1));
  }

  int h (_type key,int poz) {

    return (this->h1 (key)+1LL*poz*this->h2 (key))%this->hash_size;
  }

  public:
  hash_table (int N) {
    int i;

    this->hash_size=get_prime ((int)((double)OFFSET*N));
    this->T=new _type[this->hash_size];
    this->F=new int[this->hash_size];

    for (i=0; i<this->hash_size; ++i)
      this->F[i]=NIL;
  }

  int find (_type key) {
    int i,j;

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

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

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

    return -1;
  }

  int insert (_type key) {
    int i,j,is;

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

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

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

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

    return -1;
  }

  int erase (_type key) {
    int is;

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

    this->F[is]=DEL;
    return is;
  }
};

int main () {
  assert (freopen ("hashuri.in","r",stdin));
  assert (freopen ("hashuri.out","w",stdout));
  int T,i,x,tip;

  assert (scanf ("%d",&T));
  hash_table <int> Hash (T);

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

    assert (scanf ("%d%d",&tip,&x));

    if (tip==1)
        Hash.insert (x);

    if (tip==2)
        Hash.erase (x);

    if (tip==3) {

      if (Hash.find (x)!=-1)
        printf ("1\n");
      else
        printf ("0\n");
    }
  }
}