Pagini recente » Cod sursa (job #1714128) | Istoria paginii runda/ccex2015-10/clasament | Solutii Pariuri | Cod sursa (job #2894069) | Cod sursa (job #907553)
Cod sursa(job #907553)
#include<iostream>
#include<vector>
#include<stdlib.h>
#include<time.h>
#include<fstream>
#include<ctype.h>
using namespace std;
class CuckooHash
{
private:
int hashA1,hashA2,hashB1,hashB2;
int M1,M2,size,limit;
int uninserted,prime;
int *Hash1,*Hash2;
void makeSizes(void);
int hashFunction1(int x);
int hashFunction2(int x);
void remakeFunctions(void);
int reinsert(int x);
int rehash(void);
int insertTry(int x);
public:
CuckooHash(void);
CuckooHash(int M1,int M2);
int insert(int x);
int remove(int x);
int find(int x);
};
CuckooHash::CuckooHash(void)
{
srand(time(NULL));
makeSizes();
prime = 1000000009;
Hash1 = new int[2000000];
Hash2 = new int[2000000];
remakeFunctions();
}
CuckooHash::CuckooHash(int M1,int M2)
{
this->M1 = M1;
this->M2 = M2;
prime = 1000000009;
Hash1 = new int[1500000];
Hash2 = new int[1500000];
remakeFunctions();
}
int CuckooHash::hashFunction1(int x)
{
return ((1LL*hashA1*x+hashA2)%prime)%M1;
}
int CuckooHash::hashFunction2(int x)
{
return ((1LL*hashB2*x+hashB1)%prime+(1LL*hashB2*x)%prime)%M2;
}
void CuckooHash::remakeFunctions(void)
{
hashA1 = rand()%prime;
hashA2 = rand()%prime;
hashB1 = rand()%prime;
hashB2 = rand()%prime;
}
void CuckooHash::makeSizes(void)
{
this->M1 = 1500000 + rand()%500000;
this->M2 = 1500000 + rand()%500000;
this->M1 += 1-(this->M1 & 1);
this->M2 += 1-(this->M2 & 1);
}
inline int CuckooHash::rehash(void)
{
vector<int> aux;
aux.push_back(uninserted);
for(int i=0;i<M1;i++)
if(Hash1[i])
aux.push_back(Hash1[i]);
for(int i=0;i<M2;i++)
if(Hash2[i])
aux.push_back(Hash2[i]);
int i = aux.size()-2;
for(;;)
{
for(i++;i>=0;i--)
remove(aux[i]);
makeSizes();
remakeFunctions();
for(i=0;i<aux.size();i++)
if(!insertTry(aux[i]))
break;
if(i == aux.size())
{
aux.clear();
return 1;
}
}
return 0;
}
inline int CuckooHash::reinsert(int x)
{
int hash_funct2 = hashFunction2(x);
if(size == 0)
{
uninserted = x;
return 0;
}
if(Hash2[hash_funct2])
{
int y = Hash2[hash_funct2];
Hash2[hash_funct2] = x;
-- size;
return reinsert(y);
}
else
{
Hash2[hash_funct2] = x;
return 1;
}
}
inline int CuckooHash::insertTry(int x)
{
int hash_funct1 = hashFunction1(x);
if(find(x))
{
return 1;
}
if(Hash1[hash_funct1])
{
int y = Hash1[hash_funct1];
Hash1[hash_funct1] = x;
size = 20;
return reinsert(y);
}
else
{
Hash1[hash_funct1] = x;
return 1;
}
}
inline int CuckooHash::insert(int x)
{
if(!insertTry(x))
{
rehash();
}
return 1;
}
inline int CuckooHash::remove(int x)
{
int hash_funct1 = hashFunction1(x);
int hash_funct2 = hashFunction2(x);
if(Hash1[hash_funct1] == x)
{
Hash1[hash_funct1] = 0;
return 1;
}
else if(Hash2[hash_funct2] == x)
{
Hash2[hash_funct2] = 0;
return 1;
}
return -1;
}
inline int CuckooHash::find(int x)
{
int hash_funct1 = hashFunction1(x);
int hash_funct2 = hashFunction2(x);
if(Hash1[hash_funct1] == x)
{
return 1;
}
else if(Hash2[hash_funct2] == x)
{
return 1;
}
return 0;
}
char S[10000002];
inline int getInt(int *i)
{
int rez = 0;
for(;!isdigit(S[*i]);++(*i));
for(;isdigit(S[*i]);rez = rez*10+(S[*i])-'0',++(*i));
return rez;
}
int main()
{
ifstream f("hashuri.in");
ofstream g("hashuri.out");
f.getline(S,sizeof(S),EOF);
int N,op,a,k = 0;
CuckooHash Hash;
N = getInt(&k);
// f >> N;
for(int i=1;i<=N;i++)
{
op = getInt(&k);
a = getInt(&k);
// f >> op >> a;
switch(op)
{
case 1 : Hash.insert(a);
break;
case 2 : Hash.remove(a);
break;
case 3 : g << Hash.find(a) << "\n";
}
}
f.close();
g.close();
}