Pagini recente » Cod sursa (job #571399) | Cod sursa (job #2632478) | Cod sursa (job #1445489) | Cod sursa (job #2970279) | Cod sursa (job #936750)
Cod sursa(job #936750)
#include <fstream>
#include <iostream>
#include <vector>
#include <time.h>
#include <cstdlib>
using namespace std;
/*------------------------------------------------------*/
// Clasa de Baza ->
template <class Temp>
class Hash_Base
{
public:
virtual void generate_random() = 0;
virtual int hash_function1(Temp&) = 0;
virtual int hash_function2(Temp&) = 0;
virtual bool insert (Temp&) = 0;
virtual bool erase (Temp&) = 0;
virtual bool find (Temp&) = 0;
virtual void operator *= (Temp&) = 0;
virtual void operator /= (Temp&) = 0;
virtual bool operator %= (Temp&) = 0;
int a1,b1,a2,b2,prim;
Temp * table1;
Temp * table2;
int hash_size;
vector < pair <Temp,bool> > *operations;
};
/*--------------------------------------------------------*/
// Cuckoo Hash pentru Int32 ->
class Hash_Integer : public Hash_Base<int>
{
int hash_function1(int&);
int hash_function2(int&);
void generate_random();
public:
bool insert(int&);
bool erase(int&);
bool find(int&);
Hash_Integer(int size)
{
table1 = new int[size];
table2 = new int[size];
prim = 1000000009;
operations = new vector < pair<int,bool> >;
fill(table1 , table1 + size , 0);
fill(table2 , table2 + size , 0);
srand(time(NULL));
hash_size = size;
generate_random();
}
void operator *= (int&);
void operator /= (int&);
bool operator %= (int&);
};
void Hash_Integer::generate_random()
{
a1 = rand() % hash_size;
a2 = rand() % hash_size;
b1 = rand() % hash_size;
b2 = rand() % hash_size;
}
int Hash_Integer::hash_function1(int & value)
{
return (((long long)a1 + (long long)value * (long long)b1 ) % (long long)prim) % (long long)hash_size;
}
int Hash_Integer::hash_function2(int & value)
{
return (((long long)a2 + (long long)value * (long long)b2 ) % (long long)prim) % (long long)hash_size;
}
bool Hash_Integer::erase(int & value)
{
int h1 = hash_function1(value);
int h2 = hash_function2(value);
if (table1[h1] == value)
{
table1[h1] = 0;
return true;
}
if (table2[h2] == value)
{
table2[h2] = 0;
return true;
}
return false;
}
bool Hash_Integer::find(int & value)
{
int h1 = hash_function1(value);
int h2 = hash_function2(value);
if (table1[h1] == value)
{
return true;
}
if (table2[h2] == value)
{
return true;
}
return false;
}
bool Hash_Integer::insert(int & value)
{
if (find(value)) return true;
char which = 1;
for (int i =0;i<30;i++)
{
int h1 = hash_function1(value);
int h2 = hash_function2(value);
if (table1[h1] == 0)
{
table1[h1] = value;
return true;
}
else if(table2[h2] == 0)
{
table2[h2] = value;
return true;
}
else
{
if (which == 1)
{
swap(value,table1[h1]);
}
else
{
swap(value,table2[h2]);
}
which = - which;
}
}
return false;
}
void Hash_Integer::operator/= (int &value)
{
if (erase(value))
{
operations -> push_back(make_pair(value,false));
}
}
bool Hash_Integer::operator%= (int & value)
{
return find(value);
}
void Hash_Integer::operator*=(int & value)
{
operations -> push_back(make_pair(value,true));
if (insert(value) == false)
{
generate_random();
fill(table1 , table1 + hash_size , 0);
fill(table2 , table2 + hash_size , 0);
bool ok = false;
while (ok == false)
{
ok = true;
for (int i =0;i<operations -> size();i++)
{
bool op = (*operations)[i].second;
int data = (*operations)[i].first;
if (op)
{
if (!insert(data))
{
ok = false;
break;
}
}
else
{
erase(data);
}
}
}
}
}
int main()
{
Hash_Base<int> *t = new Hash_Integer(850000);
ifstream input("hashuri.in");
ofstream output("hashuri.out");
int n;
input >> n;
for (int i =0;i<n;i++)
{
int op , x;
input >> op >> x;
if (op == 1)
{
*t *= x;
}
if (op == 2)
{
*t /= x;
}
if (op == 3)
{
output << (*t %= x) << "\n";
}
}
return 0;
}