Pagini recente » Cod sursa (job #140679) | Cod sursa (job #3311894) | Cod sursa (job #3315099) | Cod sursa (job #3354034) | Cod sursa (job #3325546)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("hashuri.in");
ofstream fout("hashuri.out");
class Hash
{
public:
int n; /// Am scos const pentru a putea atribui in constructor, sau il poti pune in lista de initializare
vector<int> *H; /// Hash Table pentru numere
vector<string> *Hs; /// Hash Table Stringuri
vector<string> *Prefix; /// Hash Table Prefixe
Hash(int _n = 666013)
{
this->n = _n;
/// Alocam dinamic vectori
H = new vector<int>[n + 5];
Hs = new vector<string>[n + 5];
Prefix = new vector<string>[n + 5];
}
~Hash()
{
delete[] H;
delete[] Hs;
delete[] Prefix;
}
int Modulo(int x)
{
int res = x % n;
if (res < 0) res += n; /// Tratare numere negative
return res;
}
int Modulo_String(string x)
{
int i;
long long p, nr;
nr = 0;
p = 1;
for (i = 0; x[i] != 0; i++)
{
nr = (nr + (x[i] - 'a' + 1) * p) % n;
p = (p * 137) % n;
}
return nr;
}
void Insert(int x)
{
int index = Modulo(x);
/// Putem verifica daca exista deja pentru a evita duplicatele, dar e mai costisitor
/// Pentru viteza maxima la insert, dam doar push_back
H[index].push_back(x);
}
void Insert_String(string x)
{
int index = Modulo_String(x);
Hs[index].push_back(x);
}
/// STERGE ELEMENT - Optimizat pentru Vector O(1)
void Delete(int x)
{
int index = Modulo(x);
/// Parcurgem vectorul bucket-ului
const int lg = H[index].size();
for (int i = 0; i < lg; i++)
{
if (H[index][i] == x)
{
/// 1. Copiem ultimul element peste cel pe care vrem sa il stergem
H[index][i] = H[index].back();
/// 2. Scoatem ultimul element (acum duplicat)
H[index].pop_back();
return; /// Ne oprim, am sters elementul
}
}
}
void Delete_String(string x)
{
int index = Modulo_String(x);
const int lg = H[index].size();
for (int i = 0; i < lg; i++)
{
if (Hs[index][i] == x)
{
Hs[index][i] = Hs[index].back();
Hs[index].pop_back();
return;
}
}
}
void Delete_Prefix(string x)
{
string s;
int i;
long long p, nr;
nr = 0;
p = 1;
for (i = 0; x[i] != 0; i++)
{
/// Recalculam hash-ul pentru fiecare prefix
nr = (nr + (x[i] - 'a' + 1) * p) % n;
p = (p * 137) % n;
s.push_back(x[i]);
const int lg = Prefix[nr].size();
/// Cautam prefixul 's' in bucket-ul 'nr'
for(int j = 0; j < lg; j++)
if(Prefix[nr][j] == s) /// Atentie: comparam cu 's' (prefixul curent), nu cu 'x' (tot cuvantul)
{
Prefix[nr][j] = Prefix[nr].back();
Prefix[nr].pop_back();
break; /// Am gasit si sters prefixul curent, trecem la urmatorul prefix
}
}
}
void Afisare()
{
for (int i = 0; i < n; i++)
{
if (!H[i].empty())
{
cout << "Index " << i << ": ";
for (int val : H[i]) /// Range-based for (mai curat)
cout << val << " ";
cout << "\n";
}
}
}
bool Find(int x)
{
int index = Modulo(x);
/// Parcurgere specifica vector (index sau range-based)
for (int val : H[index])
if (val == x) return true;
return false;
}
bool Find_String(string x)
{
int index = Modulo_String(x);
for (const string &s : Hs[index]) /// Folosim const string& pentru a evita copierea stringului la fiecare pas
if (s == x) return true;
return false;
}
bool Find_Prefix(string x)
{
int index = Modulo_String(x);
for (const string &s : Prefix[index])
if (s == x) return true;
return false;
}
virtual void Add_Prefix(string x)
{
string s;
int i;
long long p, nr;
nr = 0;
p = 1;
for (i = 0; x[i] != 0; i++)
{
nr = (nr + (x[i] - 'a' + 1) * p) % n;
p = (p * 137) % n;
s.push_back(x[i]);
Prefix[nr].push_back(s);
}
}
void Find_Longest_Prefix(string x)
{
string s, aux;
int i, lg;
long long p, nr;
nr = lg = 0;
p = 1;
aux = x;
/// Aici logica pare a fi: daca nu gasim prefixe, returnam stringul initial?
/// Am lasat logica ta originala.
for (i = 0; x[i] != 0; i++)
{
nr = (nr + (x[i] - 'a' + 1) * p) % n;
p = (p * 137) % n;
s.push_back(x[i]);
if (!Prefix[nr].empty() && Find_Prefix(s))
{
lg = i + 1;
aux = s;
}
}
cout << aux << " ";
}
};
class Hashuri : public Hash
{
public:
Hashuri(int _n = 123457) : Hash(_n)
{ }
void Rezolvare()
{
int op, n, i, x;
fin >> n;
for(i=1; i<=n; i++)
{
fin >> op >> x;
if(op == 1) Insert(x);
else if(op == 2) Delete(x);
else fout << Find(x) << "\n";
}
}
};
int main()
{
ios_base::sync_with_stdio(0);
fin.tie(0);
fout.tie(0);
Hashuri A;
A.Rezolvare();
fin.close();
fout.close();
return 0;
}