Cod sursa(job #3313256)

Utilizator Razvan23Razvan Mosanu Razvan23 Data 2 octombrie 2025 23:18:59
Problema Hashuri Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.32 kb
#include<bits/stdc++.h>
using namespace std;

ifstream fin("hashuri.in");
ofstream fout("hashuri.out");

class Hash
{
public:
    int prime[2] = {3999989, 7999993};
    int poz, n, numere;
    list<int> *H; /// Hash Table pentru numere
    list<string> *Hs; /// Hash Table Stringuri
    list<string> *Prefix; /// Hash Table Prefixe
    Hash()
    {
        ///mentinem pozitia numarului prim, adica dimensiunea
        poz = numere = 0;
        n = prime[poz];
        /// Alocam dinamic
        H = new list<int>[n];
        Hs = new list<string>[n];
        Prefix = new list<string>[n];
    }
    ~Hash()
    {
        delete []H;
        delete []Hs;
        delete []Prefix;
    }
    int Modulo(int x) /// Vedem la ce pozitie in Hash Table se afla x
    {
        return x % n;
    }
    double LoadFactor()
    {
        return (double)numere / n;
    }
    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 * 32) % n;
        }
        return nr;
    }
    void Insert(int x)
    {
        int index = Modulo(x);
        H[index].push_back(x);
        numere++;
        if (LoadFactor() > 0,75) Rehash();
    }
    void Insert_String(string x)
    {
        int index = Modulo_String(x);
        Hs[index].push_back(x);
    }
    void Delete(int x)
    {
        int index = Modulo(x);
        list <int> :: iterator it; /// Iterator pentru parcurgere
        for (it = H[index].begin(); it != H[index].end() && *it != x; it++);
        if(it != H[index].end()) H[index].erase(it);
    }
    void Delete_String(string x)
    {
        int index = Modulo_String(x);
        list <string> :: iterator it;
        for (it = Hs[index].begin(); it != Hs[index].end() && *it != x; it++);
        if(it != Hs[index].end()) Hs[index].erase(it);
    }
    void Delete_Prefix(string x)
    {
        list <string> :: iterator it;
        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 * 32) % n;
            for (it = Prefix[nr].begin(); it != Prefix[nr].end() && *it != x; it++);
            if(it != Prefix[nr].end()) Prefix[nr].erase(it);
        }
    }
    void Afisare()
    {
        int i;
        for (i = 0; i < n; i++)
        {
            for (auto w : H[i])
                cout << w << " ";
            cout << "\n";
        }
    }
    bool Find(int x)
    {
        int index = Modulo(x);
        list<int>::iterator it;
        for (it = H[index].begin(); it != H[index].end(); it++)
            if (*it == x) return true;
        return false;
    }
    bool Find_String(string x)
    {
        int index = Modulo_String(x);
        list<string>::iterator it;
        for (it = Hs[index].begin(); it != Hs[index].end(); it++)
            if (*it == x) return true;
        return false;
    }
    bool Find_Prefix(string x)
    {
        int index = Modulo_String(x);
        list<string>::iterator it;
        for (it = Prefix[index].begin(); it != Prefix[index].end(); it++)
            if (*it == 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 * 32) % 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;
        for(i=0; x[i]!=0; i++)
        {
            nr = (nr + (x[i] - 'a' + 1) * p) % n;
            p = (p * 32) % n;
            s.push_back(x[i]);
            if(Prefix[nr].size() != 0 && Find_Prefix(s) == true)
            {
                lg = i + 1;
                aux = s;
            }
        }
        cout << aux << " ";
    }
    void ShowDistribution()
    {
        int i;
        for (i = 0; i < n; i++)
            cout << "Bucket " << i << ": " << H[i].size() << " elemente\n";
    }
    void Rehash()
    {
        if(poz == 1) return;
        poz++;
        int n_nou, i;
        n_nou = prime[poz];
        list<int>* H_nou = new list<int>[n_nou];
        for(i = 0; i < n; i++)
            {
                for (int x : H[i])
                {
                    int index = x % n_nou;
                    H_nou[index].push_back(x);
                }
            }
        delete[] H;
        H = H_nou;
        n = n_nou;
    }

};

class Hashuri : public Hash
{
public:
    Hashuri() : Hash()
    { }
    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;
}