Cod sursa(job #2891153)

Utilizator AndreiAncutaAndrei Ancuta AndreiAncuta Data 17 aprilie 2022 18:21:06
Problema Hashuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.67 kb
#include <array>
#include <cstdlib>
#include <fstream>

struct Node {
    int value;
    Node *next = nullptr;
};

template <std::size_t P> class HashSet {
protected:
    std::array<Node *, P> buckets{0};

    unsigned hash(int x) { return std::abs((int)(x % P)); }

public:
    bool contains(int x) {
        const auto bucket_head = buckets[hash(x)];
        auto node = bucket_head;

        while (node != nullptr) {
            if (node->value == x) {
                return true;
            }
            node = node->next;
        }

        return false;
    }

    bool insert(int x) {
        const auto key = hash(x);
        const auto bucket_head = buckets[key];

        auto last = bucket_head;
        if (bucket_head != nullptr) {
            auto node = bucket_head;
            while (true) {
                if (node->value == x) {
                    // x already exists
                    return false;
                }
                node = node->next;
                if (node == nullptr) {
                    break;
                }
                last = node;
            }
        }

        if (last != nullptr) {
            last->next = new Node{x, nullptr};
        } else {
            // Inserting the first node in the bucket
            buckets[key] = new Node{x, nullptr};
        }

        return true;
    }

    bool remove(int x) {
        auto key = hash(x);
        const auto bucket_head = buckets[key];

        if (bucket_head == nullptr)
            return false;

        auto node = bucket_head;
        Node *last = nullptr;
        while (true) {
            if (node->value == x) {
                // Found x, remove it
                if (last != nullptr) {
                    last->next = node->next;
                } else {
                    // x was the first element in the bucket
                    buckets[key] = node->next;
                }
                delete node;
                return true;
            }
            node = node->next;
            if (node == nullptr) {
                break;
            }
            last = node;
        }

        // x was not found
        return false;
    }
};

int main() {
    std::ifstream ifs("hashuri.in");
    std::ofstream ofs("hashuri.out");

    unsigned n;
    ifs >> n;

    HashSet<1'000'003> set;

    for (unsigned i = 0; i < n; i++) {
        int op;
        int x;
        ifs >> op >> x;

        switch (op) {
        case 1:
            set.insert(x);
            break;
        case 2:
            set.remove(x);
            break;
        case 3:
            ofs << (set.contains(x) ? 1 : 0) << '\n';
            break;
        }
    }

    ifs.close();
    ofs.close();

    return 0;
}