Pagini recente » Cod sursa (job #18926) | Cod sursa (job #624534) | Cod sursa (job #2976135) | Cod sursa (job #2526037) | Cod sursa (job #1710616)
#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <limits>
using namespace std;
template<typename T, typename V>
class HashTable
{
private:
const int numberOfPrimes = 8;
const vector<int> primes{61,67,71,73,79,83,89,97};
int prime;
int generatePrime()
{
srand(time(nullptr));
return primes[rand() % numberOfPrimes];
}
void init(unique_ptr<pair<T,V>[]>& _table)
{
for (int i = 0; i < MAX_SIZE; ++i)
{
_table[i].first = EMPTY;
_table[i].second = V();
}
}
int MAX_SIZE = 1 << 5;
int MASK = MAX_SIZE - 1;
const int EMPTY = numeric_limits<T>::min();
const int ERASED = numeric_limits<T>::min() + 1;
unique_ptr<pair<T,V>[]> table;
size_t _size;
void insert(unique_ptr<pair<T,V>[]>& _table, const T& key, const V& value)
{
int p = (prime * key) & MASK;
while (_table[p].first != key && _table[p].first != EMPTY && _table[p].first != ERASED)
p = (p + 1) & MASK;
_table[p].first = key;
_table[p].second += value;
_size++;
}
void erase(unique_ptr<pair<T,V>[]>& _table, const T& key)
{
int p = (prime * key) & MASK;
while (_table[p].first != key && _table[p].first != EMPTY)
p = (p + 1) & MASK;
if (_table[p].first == key)
{
_table[p].first = ERASED;
_table[p].second = V();
_size--;
}
}
V find(const unique_ptr<pair<T,V>[]>& _table, const T& key) const
{
int p = (prime * key) & MASK;
while (_table[p].first != key && _table[p].first != EMPTY)
p = (p + 1) & MASK;
if (_table[p].first == key)
return _table[p].second;
else
return V();
}
void rehash()
{
unique_ptr<pair<T,V>[]> _table(new pair<T,V>[2 * MAX_SIZE]);
for (int i = 0; i < MAX_SIZE; ++i)
if (table[i].first != ERASED && table[i].first != EMPTY)
this->insert(_table, table[i].first, table[i].second);
table = std::move(_table);
MAX_SIZE *= 2;
MASK = MAX_SIZE - 1;
}
public:
HashTable() : prime(generatePrime()), table(), _size(0)
{
static_assert(std::is_integral<T>::value, "Integer required.");
table = make_unique<pair<T,V>[]>(MAX_SIZE);
this->init(table);
}
void insert(const T& key, const V& value)
{
this->insert(table, key, value);
if (70.0 * MAX_SIZE / 100.0 < _size)
rehash();
}
void erase(const T& key)
{
this->erase(table, key);
}
V find(const T& key) const
{
return this->find(table, key);
}
};
int main()
{
ifstream in("hashuri.in");
ofstream out("hashuri.out");
HashTable<int,int> T;
int N, X, tip;
in >> N;
while (N--)
{
in >> tip >> X;
if (tip == 1)
T.insert(X, 1);
else if (tip == 2)
T.erase(X);
else
out << (T.find(X) > 0) << "\n";
}
return 0;
}