Cod sursa(job #904443)

Utilizator brainwashed20Alexandru Gherghe brainwashed20 Data 4 martie 2013 13:45:48
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 4.04 kb
#include<fstream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<ctime>

using namespace std;

class cockooHash {

    int *H1, *H2, size, limit;
    unsigned prime;
    int a1, b1, a2, b2;
    bool *viz1, *viz2;

    void make_hash_function(int &a, int &b) {
        a = rand() % size;
        b = rand() % size;
    }

    int hash1(int val) {
        return(((long long)this->a1 * (long long)val + (long long)this->b1) % (long long)this->prime) % size;
    }

     int hash2(int val) {
       return(((long long)this->a2 * (long long)val + (long long)this->b2) % (long long)this->prime) % size;
    }

    void rehash() {
        make_hash_function(this->a1, this->b1);
        make_hash_function(this->a2, this->b2);
    }

    public:
    cockooHash(int size) {

        this->size = size;
        this->limit = (int)log2(size);
        this->prime = 402653189;

        this->H1 = new int[size];
        this->H2 = new int[size];
        memset(this->H1, 0, sizeof(this->H1));
        memset(this->H2, 0, sizeof(this->H2));
        //fill(this->H1, this->H1+size, 0);
        //fill(this->H2, this->H2+size, 0);

        this->viz1 = new bool[size];
        this->viz2 = new bool[size];
        memset(this->viz1, 0, sizeof(this->viz1));
        memset(this->viz2, 0, sizeof(this->viz1));
        //fill(this->viz1, this->viz1+size, false);
        //fill(this->viz2, this->viz2+size, false);

        make_hash_function(this->a1, this->b1);
        make_hash_function(this->a2, this->b2);
    }

    bool find(int val) {

        int poz1 = this->hash1(val);
        int poz2 = this->hash2(val);

        if(this->H1[poz1] == val && this->viz1[poz1] == true)
            return true;
        if(this->H2[poz2] == val && this->viz2[poz2] == true)
            return true;

        return false;
    }

    bool erase(int val) {

        int poz1 = this->hash1(val);
        int poz2 = this->hash2(val);

        if(this->H1[poz1] == val && this->viz1[poz1] == true) {
            this->viz1[poz1] = false;
            return true;
        }

        if(this->H2[poz2] == val && this->viz2[poz2] == true) {
            this->viz2[poz2] = false;
            return true;
        }

        return false;
    }

    bool insert(int val) {

        int i, x, poz1, poz2;

        x = val;
        poz1 = this->hash1(x);
        poz2 = this->hash2(x);

        if(this->viz1[poz1] == false) {
            this->H1[poz1] = x;
            this->viz1[poz1] = true;
            return true;
        }

        for(i=0; i<limit; i+=2) {
            if(this->viz2[poz2] == false) {
                this->H2[poz2] = x;
                this->viz2[poz2] = true;
                return true;
            }

            swap(x, this->H2[poz2]);
            poz1 = this->hash1(x);
            poz2 = this->hash2(x);

            if(this->viz1[poz1] == false) {
                this->H1[poz1] = x;
                this->viz1[poz1] = true;
                return true;
            }

            swap(x, this->H1[poz1]);
            poz1 = this->hash1(x);
            poz2 = this->hash2(x);
        }

        //e nevoie de rehash
        return false;
    }

};

bool remake_hash() {

    ifstream f("hashuri.in");
    ofstream g("hashuri.out");

    int Q, op, val;
    bool ok;
    cockooHash myHash(666013);

    f>>Q;
    while(Q--) {
        f>>op>>val;
        if(op == 1) {
            if(!myHash.find(val))
                ok = myHash.insert(val);
                if(!ok)
                    return false;
        }
        if(op == 2) {
            if(myHash.find(val))
                myHash.erase(val);
        }
        if(op == 3) {
            if(myHash.find(val) == false)
                g<<0<<"\n";
            else
                g<<1<<"\n";
        }
    }

    f.close();
    g.close();

    return true;
}

int main() {

    srand(time(0));

    bool ok;

    ok = false;
    while(!ok)
        ok = remake_hash();

    return 0;
}