Cod sursa(job #937701)

Utilizator vladm97Matei Vlad vladm97 Data 10 aprilie 2013 21:30:36
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.63 kb
#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<time.h>
#include<string>
#include<string.h>
#include<stdio.h>
#include<math.h>
using namespace std;

template<class T>
class Hash{
protected:
    T *v1;
    T *v2;
    int size;
    int prim;
    int a1;
    int a2;
    char *fin;
    char *fout;

public:
    Hash(char*, char*);
    ~Hash();

    bool operator+=(T x);
    void operator-=(T x);
    bool operator[](T x);

    void null();
    virtual int h1(T x)=0;
    virtual int h2(T x)=0;
    void sp();
    void reset();
    void rehash(int k);
};

class Hash_int:public Hash<int>
{
public:
    Hash_int(char*in,char*out):Hash(in,out)
    {

    }
    int h1(int);
    int h2(int);

} ;

class Hash_float:public Hash<float>
{
public:
    Hash_float(char*in,char*out):Hash(in,out)
    {

    }
    int h1(float);
    int h2(float);
};

class Hash_char:public Hash<char>
{
public:
    Hash_char(char*in,char*out):Hash(in,out)
    {

    }
    int h1(char);
    int h2(char);
};

class Hash_string:public Hash<string>
{
public:
    Hash_string(char*in,char*out):Hash(in,out)
    {

    }

    int h1(string);
    int h2(string);
};

int main()
{
    Hash_int t("hashuri.in","hashuri.out");
    t.sp();
}

int Hash_int:: h1(int x)
{
    return (((long long) x*(long long)(a1%10)+(long long)x%a2)+(long long)x*5)%size;
}

int Hash_int:: h2(int x)
{
   return (((long long)x*((long long)(a1%10))%prim)+(long long)x*(long long)(a1%10))%size;
}

int Hash_float:: h1(float x)
{
    int exp;
    float result=frexp(x,&exp);
    return (((long long) exp*(long long)(a1%10)+(long long)exp%a2)+(long long)exp*5)%size;
}

int Hash_float:: h2(float x)
{
    int exp;
    float result=frexp(x,&exp);
    return (((long long)exp*((long long)(a1%10))%prim)+(long long)exp*(long long)(a1%10))%size;
}

int Hash_char:: h1(char x){
    int y=(int) x;
    return (((long long) y*(long long)(a1%10)+(long long)y%a2)+(long long)y*5)%size;
}

int Hash_char:: h2(char x){
    int y=(int) x;
    return (((long long)y*((long long)(a1%10))%prim)+(long long)y*(long long)(a1%10))%size;
}

int Hash_string:: h1(string x)
{
    int suma=0,i,lung;
    lung=x.length();
    for(i=0;i<lung;i++)
        suma=suma+x[i]*i;
    return (((long long)suma*(long long)(a1%10)+(long long)suma%a2)+(long long)suma*5)%size;
}

int Hash_string:: h2(string x)
{
    int suma=0,i,lung;
    lung=x.length();
    for(i=0;i<lung;i++)
        suma=suma+x[i]*i;
    return (((long long)suma*((long long)(a1%10))%prim)+(long long)suma*(long long)(a1%10))%size;
}

template<class T>
void Hash<T>:: sp()
{
    srand(time(NULL));
    reset();
    null();

    ifstream f(fin);
    ofstream g(fout);

    int n,op,i;
    T x;
    f>>n;
    for(i=1;i<=n;i++){
      f>>op>>x;
        if(op==1)
            {if(((*this)+=x)==false)rehash(i);}
        if(op==2){
            if((*this)[x]==1)
               (*this)-=x;
        }
        if(op==3){
                if((*this)[x]==1)
                    g<<1<<"\n";
                else g<<0<<"\n";
        }
    }
}

template<class T>
void Hash<T>:: null()
{
    int i;
    for(i=0;i<size;i++)
        v1[i]=v2[i]=0;
}

template<class T>
void Hash<T>:: reset()
{
    a1=rand()%prim;
    a2=rand()%prim;
}

template<class T>
bool Hash<T>:: operator[](T x)
{
    if(v1[h1(x)]==x)return 1;
    if(v2[h2(x)]==x)return 1;
    return 0;
}

template<class T>
bool Hash<T>:: operator+=(T x)
{
    if((*this)[x]==1)return true;
    int k=0,aux;
    while(k<30){
        if(v1[h1(x)]==0){
            v1[h1(x)]=x;
            return true;}
        else if(v2[h2(x)]==0){
            v2[h2(x)]=x;
            return true;}
        else{
            k++;
            if(k%2==1){
                aux=v1[h1(x)];
                v1[h1(x)]=x;
                x=aux;}
            else{
                aux=v2[h2(x)];
                v2[h2(x)]=x;
                x=aux;}
        }
    }
    return false;
}

template<class T>
void Hash<T>:: operator-=(T x)
{
    if(v1[h1(x)]==x)v1[h1(x)]=0;
    else if(v2[h2(x)]==x)v2[h2(x)]=0;
}

template<class T>
void Hash<T>:: rehash(int k)
{
    reset();
    null();
    int i,op;
    T x;
    ifstream f(fin);
    f>>i;
    for(i=1;i<=k;i++){
        f>>op>>x;
        if(op==1)
            if((*this+=x)==false) rehash(k);

        if(op==2){
            if((*this)[x]==1)
                (*this)-=x;
        }
    }
    f.close();
}

template<class T>
Hash<T>:: Hash(char *in, char *out){
    size=1000000;
    v1=(T*)calloc(size,sizeof(T));
    v2=(T*)calloc(size,sizeof(T));
    prim=18593;
    fin=new char[strlen(in)];
    fout=new char[strlen(out)];
    strcpy(fin,in);
    strcpy(fout,out);
}

template<class T>
Hash<T>:: ~Hash(){
    delete[] v1;
    delete[] v2;
    delete[] fin;
    delete[] fout;
}