Cod sursa(job #940086)

Utilizator Aida_SilviaStrimbeanu Aida Silvia Aida_Silvia Data 15 aprilie 2013 16:32:08
Problema Hashuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 4.05 kb
#include <iostream>
#include <fstream>
#include<cstdlib>
#include<ctime>
#define ll long long
#include <vector>

using namespace std;

template <class tip>
class hashbase
{

public:

    hashbase(int);
    ~hashbase();

    virtual bool insert(tip &)=0;
    virtual bool find(tip &)=0;
    virtual bool erase(tip &)=0;

    virtual int functie1(tip &)=0;
    virtual int functie2(tip &)=0;

    void operator+=(tip &);
    void operator-=(tip &);
    bool operator==(tip &);


    tip *hash1,*hash2;
    const static int prime_nr = 1000000009;
    int a1,a2,b1,b2,hash_size;

    vector < pair<bool,tip> > operatii;

    void generate();
};

template<class tip>
void hashbase<tip>::operator+=(tip &value)
{
    operatii.push_back(make_pair(true,value));

    if (insert(value) == false)
    {
        bool ok=false;
        while (!ok)
        {
            fill(hash1,hash1+hash_size,0);
            fill(hash2,hash2+hash_size,0);
            ok = true;
            generate();
            for(int i=0;i<operatii.size() && ok;i++)
                if (operatii[i].first) ok = insert(operatii[i].second);
                else erase(operatii[i].second);
        }
    }
}

template<class tip>
void hashbase<tip>::operator-=(tip &value)
{
    if (erase(value))
     operatii.push_back(make_pair(false,value));
}

template<class tip>
bool hashbase<tip>::operator==(tip &value)
{
    return find(value);
}

template<class tip>
hashbase<tip>::hashbase(int size)
{
    hash_size=size;
    hash1=new tip[hash_size];
    hash2=new tip[hash_size];
    generate();
}

template<class tip>
hashbase<tip>::~hashbase()
{
    delete[] hash1;
    delete[] hash2;
}

template<class tip>
void hashbase<tip>::generate()
{
    srand(time(0));
    a1=rand() % hash_size;
    b1=rand() % hash_size;
    a2=rand() % hash_size;
    b2=rand() % hash_size;
}


class hash_integer:public hashbase<int>
{
public:
    bool insert(int &);
    bool find(int &);
    bool erase(int &);
    int functie1(int &);
    int functie2(int &);

    hash_integer(int size) : hashbase<int>(size)
    {
        fill(hash1,hash1+hash_size,0);
        fill(hash2,hash2+hash_size,0);
    }


};

int hash_integer::functie1(int & val)
{
    return ( ( ( (ll)this->a1 * (ll)val + (ll)this->b1) % (ll)this->prime_nr ) % (ll)hash_size );
}

int hash_integer::functie2(int & val)
{
    return ( ( ( (ll)this->a2 * (ll)val + (ll)this->b2) % (ll)this->prime_nr ) % (ll)hash_size );
}

bool hash_integer::insert(int &val)
{
    int  x = val;
    int k1 = functie1(x);
    int k2 = functie2(x);

    if(hash1[k1] == 0)
    {
        hash1[k1] = x;
        return true;
    }

    for(int i = 0; i<60; i+=2)
    {
        if(hash2[k2]==0)
        {
            hash2[k2] = x;
            return true;
        }

        swap(x, hash2[k2]);
        k1 = functie1(x);
        k2 = functie2(x);

        if(hash1[k1]==0)
        {
            hash1[k1] = x;
            return true;
        }

        swap(x, hash1[k1]);
        k1 = functie1(x);
        k2 = functie2(x);
    }

    return false;
}

bool hash_integer::find(int  &val)
{
    int k1, k2;

    k1 = functie1(val);
    k2 = functie2(val);

    if(hash1[k1] == val )
        return true;
    if(hash2[k2] == val )
        return true;

    return false;
}

bool hash_integer::erase(int &val)
{
    int k1 = functie1(val);
    int k2 = functie2(val);

    if(hash1[k1] == val )
    {
        hash1[k1]=0;
        return true;
    }
    if(hash2[k2] == val)
    {
        hash2[k2] = 0;
        return true;
    }

    return false;
}



int main()
{
    hashbase<int> *p = new hash_integer(900001);
    ifstream in("hashuri.in");
    ofstream out("hashuri.out");
    int n;
    in >> n;
    for (int i =0;i<n;i++)
    {
        int op , x;
        in >> op >> x;
        if (op == 1) *p += x;
        if (op == 2) *p -= x;
        if (op == 3) out << (*p == x) << "\n";
    }
    in.close();
    out.close();

    return 0;
}