Cod sursa(job #3359774)

Utilizator Razvan23Razvan Mosanu Razvan23 Data 3 iulie 2026 19:40:17
Problema Hashuri Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.84 kb
#include <cstdio>
#include <vector>
#include <cstdint>

// --- PARSER PENTRU CITIRE RAPIDA ---
class InParser {
private:
    FILE *fin;
    char *buff;
    int sp;
    const int SIZE = 65536; // 64KB

    inline char read_ch() {
        if (sp == SIZE) {
            fread(buff, 1, SIZE, fin);
            sp = 0;
        }
        return buff[sp++];
    }

public:
    InParser(const char* nume) {
        fin = fopen(nume, "r");
        buff = new char[SIZE];
        sp = SIZE;
    }
    ~InParser() {
        delete[] buff;
        if (fin) fclose(fin);
    }

    InParser& operator >> (int &n) {
        char c;
        while (!isdigit(c = read_ch()));
        n = c - '0';
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        return *this;
    }
};

// --- PARSER PENTRU SCRIERE RAPIDA ---
class OutParser {
private:
    FILE *fout;
    char *buff;
    int sp;
    const int SIZE = 65536;

public:
    OutParser(const char* nume) {
        fout = fopen(nume, "w");
        buff = new char[SIZE];
        sp = 0;
    }
    ~OutParser() {
        if (sp > 0) fwrite(buff, 1, sp, fout);
        delete[] buff;
        if (fout) fclose(fout);
    }

    OutParser& operator << (char c) {
        if (sp == SIZE) {
            fwrite(buff, 1, SIZE, fout);
            sp = 0;
        }
        buff[sp++] = c;
        return *this;
    }
};

// --- HASH TABLE OPTIMIZAT PENTRU SET ---
class HashTable
{
private:
    int HASH_SIZE;
    std::vector<int> head;
    struct Node
    {
        int key;
        int next;
    };
    std::vector<Node> nodes;
    std::vector<int> free_list;
    int node_count;
    static constexpr int HASH_BITS = 20;

    inline int get_hash(int x) const
    {
        uint32_t h = static_cast<uint32_t>(x) * 2654435769u;
        return h >> (32 - HASH_BITS);
    }

public:
    HashTable(int max_elements = 1000005)
    {
        HASH_SIZE = 1 << HASH_BITS;
        head.assign(HASH_SIZE, -1);
        nodes.resize(max_elements);
        free_list.reserve(max_elements);
        node_count = 0;
    }

    inline int allocate_node()
    {
        if (!free_list.empty())
        {
            int recycled_index = free_list.back();
            free_list.pop_back();
            return recycled_index;
        }
        return node_count++;
    }

    void Insert(int x)
    {
        int h = get_hash(x);

        for (int i = head[h]; i != -1; i = nodes[i].next)
        {
            if (nodes[i].key == x)
                return; // Elementul exista deja in set, nu facem nimic
        }

        int new_idx = allocate_node();
        nodes[new_idx].key = x;
        nodes[new_idx].next = head[h];
        head[h] = new_idx;
    }

    void Delete(int x)
    {
        int h = get_hash(x);
        int prev = -1;

        for (int i = head[h]; i != -1; prev = i, i = nodes[i].next)
        {
            if (nodes[i].key == x)
            {
                if (prev == -1) head[h] = nodes[i].next;
                else nodes[prev].next = nodes[i].next;

                free_list.push_back(i); // Reciclam nodul
                return;
            }
        }
    }

    bool Find(int x) const
    {
        int h = get_hash(x);
        for (int i = head[h]; i != -1; i = nodes[i].next)
        {
            if (nodes[i].key == x) return true;
        }
        return false;
    }
};

int main()
{
    InParser fin("hashuri.in");
    OutParser fout("hashuri.out");

    HashTable A;
    int n{}, x{}, y{};

    fin >> n;
    for(int i = 0; i < n; i++)
    {
        fin >> x >> y;
        if(x == 1) A.Insert(y);
        else if(x == 2) A.Delete(y);
        else
        {
            fout << (A.Find(y) ? '1' : '0');
            fout << '\n';
        }
    }
    return 0;
}