#include <math.h>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <math.h>
#include <vector>
using namespace std;
template <class type>
class base_hash
{
public:
base_hash <type> (){;}
virtual bool operator +=(type)=0;
virtual bool operator -=(type)=0;
virtual bool operator ==(type)=0;
virtual int function (type,int,int)=0;
virtual int hash_from_data(string,string)=0;
};
template <class type>
class cuckoo_hash:public base_hash <type> {
private:
type *h1,*h2;
int hash_size;
int a,b;
long long prim;
public:
cuckoo_hash<type>(int size,int p=1000000009)
{
h1 = new type[size];
h2 = new type[size];
hash_size = size;
fill(h1,h1+size,0);
fill(h2,h2+size,0);
prim=p;
}
~cuckoo_hash()
{
delete [] h1;
delete [] h2;
a=b=hash_size=0;
prim=0;
}
bool operator +=(type value)
{
int cycles=0,sw=1;
type aux=value;
bool found=false;
if (*(this) == value) return true;
while (!found)
{
int poz1 = function(value,a,b);
int poz2 = function(value,b,a);
cycles++;
if (h1[poz1] == 0)
{
h1[poz1] = value;
found = true;
}
else if(h2[poz2] == 0)
{
h2[poz2] = value;
found = true;
}
else
{
if (sw==1)
{
aux = value;
value = h1[poz1];
h1[poz1] = aux;
}
else
{
aux = value;
value = h2[poz2];
h2[poz2] = aux;
}
sw*=-1;
}
if ((cycles > log2(this->hash_size))&&(!found)){return false;} //numarul de incercari nu depaseste log size
}
return true;
}
bool operator -=(type value)
{
int poz1 = function(value,a,b);
int poz2 = function(value,b,a);
if (h1[poz1] == value)
{
h1[poz1] = 0;
return true;
}
else if (h2[poz2] == value)
{
h2[poz2] = 0;
return true;
}
return false;
}
bool operator ==(type value)
{
int poz1 = function(value,a,b);
int poz2 = function(value,b,a);
if (h1[poz1] == value || h2[poz2] == value)
{
return true;
}
else
{
return false;
}
}
//define function for each type
int function(int value,int a,int b)
{
return (((long long)a+(long long)value * (long long)b ) % (long long)prim )% (long long)hash_size;
}
int function(float value,int a,int b)
{
value=value*(0.61);
double integral,fractionary;
fractionary=modf(value,&integral);
return (((long long)fractionary+(long long)integral * (long long)b ) % (long long)prim )% (long long)hash_size;
}
int function(double value,int a,int b)
{
value=value*(0.61);
double integral,fractionary;
fractionary=modf(value,&integral);
return (((long long)fractionary+(long long)integral * (long long)b ) % (long long)prim )% (long long)hash_size;
}
int function(char value,int a,int b)
{
return (((long long)a+(long long)(int(value)) * (long long)b ) % (long long)prim )% (long long)hash_size;
}
void make_hash_function()
{
a = rand() % hash_size;
b = rand() % hash_size;
}
int hash_from_data (string a, string b)
{
bool ok = false;
ifstream in(a.c_str());
ofstream out(b.c_str());
while (ok == false)
{
in.clear();
int N;
make_hash_function();
in >> N;
for (int i =0;i<N;i++)
{
type x ;int op;
in >> op >> x;
if (op==1)
if ( (*(this)+=x) == false )
{
ok = false;
break;
}
if (op==2)
*(this)-=x;
if (op==3)
out << (*(this) == x) << "\n";
}
ok = true;
}
return 0;
}
};
template <class type>
class simple_hash:public base_hash <type> {
private:
vector <type> *H;
//typename vector <type>::iterator it;
int hash_size,a,b;
long long prim;
public:
simple_hash <type>(int size,int p=666013)
{
H = new vector<type> [size];
hash_size=size;
a=b=0;
prim=p;
}
~simple_hash()
{
delete [] H;
hash_size=0;
prim=0;
}
bool operator +=(type value)
{int poz;
poz=function(value,a,b);
H[poz].push_back(value);
return true;
}
bool operator -=(type value)
{
typename vector<type>::iterator it;
int poz = function(value,a,b);
for (it=H[poz].begin();it!=H[poz].end();it++)
if ((*it)==value)
{
H[poz].erase(it);
return true;
}
return false;
}
bool operator ==(type value)
{
typename vector<type>::iterator it;
int poz = function(value,a,b);
for (it=H[poz].begin();it!=H[poz].end();it++)
if (*it==value) return 1;
return 0;
}
//define function for each type
int function(int value,int a,int b)
{
return (((long long)a+(long long)(int(value)) * (long long)b ) % (long long)prim )% (long long)hash_size;
}
int function(float value,int a,int b)
{
value=value*(0.61);
double integral,fractionary;
fractionary=modf(value,&integral);
return (((long long)fractionary+(long long)integral * (long long)b ) % (long long)prim )% (long long)hash_size;
}
int function(double value,int a,int b)
{
value=value*(0.61);
double integral,fractionary;
fractionary=modf(value,&integral);
return (((long long)fractionary+(long long)integral * (long long)b ) % (long long)prim )% (long long)hash_size;
}
int function(char value,int a,int b)
{
return (((long long)a+(long long)(int(value)) * (long long)b ) % (long long)prim )% (long long)hash_size;
}
void make_hash_function()
{
a = rand() % hash_size;
b = rand() % hash_size;
}
int hash_from_data (string a, string b)
{
ifstream in(a.c_str());
ofstream out(b.c_str());
int N;
make_hash_function();
in >> N;
for (int i =0;i<N;i++)
{
type x ;int op;
in >> op >> x;
if (op==1)
*this+=x;
if (op==2)
*(this)-=x;
if (op==3)
out << (*(this) == x) << "\n";
}
return 0;
}
};
int main()
{ base_hash <int> *t;
t=new simple_hash<int>(1000005);
t->hash_from_data("hashuri.in","hashuri.out");
return 0;
}