#include <fstream>
#ifndef HASHTABLE_H_
#define HASHTABLE_H_
#include <list>
#include <iterator>
#include <iostream>
/**
* Hashtable implementation.
*/
template <typename Tkey, typename Tvalue> struct info {
Tkey key;
Tvalue value;
};
template <typename Tkey, typename Tvalue> class Hashtable {
private:
std::list<struct info<Tkey, Tvalue>> *H_;
int size_;
int capacity_;
int (*hash_)(Tkey);
public:
Hashtable(int capacity, int (*h)(Tkey));
Hashtable(const Hashtable<Tkey, Tvalue>&);
~Hashtable();
Hashtable<Tkey, Tvalue>& operator=(const Hashtable<Tkey, Tvalue>&);
void put(Tkey key, Tvalue value);
void remove(Tkey key);
Tvalue operator[](Tkey key);
bool has_key(Tkey key);
int get_size();
int get_capacity();
};
template <typename Tkey, typename Tvalue>
Hashtable<Tkey, Tvalue>::Hashtable(int capacity, int (*h)(Tkey)):
H_(nullptr), size_(0), capacity_(capacity), hash_(h) {
try {
H_ = new std::list<struct info<Tkey, Tvalue>>[capacity];
} catch (std::exception& e) {
std::cerr << "Standard exception: " << e.what() << '\n';
}
}
template <typename Tkey, typename Tvalue>
Hashtable<Tkey, Tvalue>::Hashtable(const Hashtable<Tkey, Tvalue>& other) {
try {
H_ = new std::list<struct info<Tkey, Tvalue>>[other.capacity];
} catch (std::exception& e) {
std::cerr << "Standard exception: " << e.what() << '\n';
}
for (int i = 0; i < other.capacity; ++i) {
H_[i] = other.H_[i];
}
size_ = other.size_;
capacity_ = other.capacity_;
hash_ = other.hash_;
}
template <typename Tkey, typename Tvalue>
Hashtable<Tkey, Tvalue>::~Hashtable() {
delete[] H_;
}
template <typename Tkey, typename Tvalue> Hashtable<Tkey, Tvalue>&
Hashtable<Tkey, Tvalue>::operator=(const Hashtable<Tkey, Tvalue>& other) {
delete[] H_;
try {
H_ = new std::list<struct info<Tkey, Tvalue>>[other.capacity];
} catch (std::exception& e) {
std::cerr << "Standard exception: " << e.what() << '\n';
}
for (int i = 0; i < other.capacity; ++i) {
H_[i] = other.H_[i];
}
size_ = other.size_;
capacity_ = other.capacity_;
hash_ = other.hash_;
}
template <typename Tkey, typename Tvalue>
void Hashtable<Tkey, Tvalue>::put(Tkey key, Tvalue value) {
info<Tkey, Tvalue> data = {key, value};
remove(key);
H_[hash_(key) % capacity_].push_back(data);
}
template <typename Tkey, typename Tvalue>
void Hashtable<Tkey, Tvalue>::remove(Tkey key) {
int index = hash_(key) % capacity_;
for (auto it = H_[index].begin(); it != H_[index].end(); ++it) {
if ((*it).key == key) {
H_[index].erase(it);
break;
}
}
}
template <typename Tkey, typename Tvalue>
Tvalue Hashtable<Tkey, Tvalue>::operator[](Tkey key) {
int index = hash_(key) % capacity_;
for (auto it = H_[index].begin(); it != H_[index].end(); ++it) {
if ((*it).key == key) {
return (*it).value;
}
}
std::cerr << "Standard exception: key not found\n";
return Tvalue();
}
template <typename Tkey, typename Tvalue>
bool Hashtable<Tkey, Tvalue>::has_key(Tkey key) {
int index = hash_(key) % capacity_;
for (auto it = H_[index].begin(); it != H_[index].end(); ++it) {
if ((*it).key == key) {
return true;
}
}
return false;
}
template <typename Tkey, typename Tvalue>
int Hashtable<Tkey, Tvalue>::get_size() {
return size_;
}
template <typename Tkey, typename Tvalue>
int Hashtable<Tkey, Tvalue>::get_capacity() {
return capacity_;
}
#endif // HASHTABLE_H_
int int_hash(int number) {
return number;
}
int main() {
std::ifstream fin("hashuri.in");
std::ofstream fout("hashuri.out");
Hashtable<int, int> ht(666013, int_hash);
int N, q, x;
fin >> N;
for (int i = 0; i < N; ++i) {
fin >> q >> x;
switch(q) {
case 1:
ht.put(x, 1);
break;
case 2:
ht.remove(x);
break;
default:
fout << ht.has_key(x) << '\n';
}
}
fin.close();
fout.close();
return 0;
}