# Задача 10 — хеш-таблица с открытой адресацией (C++) Свой контейнер, без `std::unordered_map`. Разрешение коллизий — **линейное зондирование** (linear probing), ёмкость — степень двойки, при загрузке > 0.7 таблица **перехешируется** вдвое. Индексация — через маску `idx & (capacity - 1)`, а не `%`. ```c++ class HashTable { public: explicit HashTable(std::size_t initial_capacity = 16); void put(int key, int value); // обновляет значение, если ключ уже есть bool get(int key, int& out) const; // false — ключа нет bool erase(int key); // false — ключа не было std::size_t size() const; std::size_t capacity() const; // степень двойки, >= 16 }; ``` Требования: - `put` 100 000 ключей — суммарно быстрее 2 секунд (в среднем O(1)); - ключи с совпадающими младшими битами (например, все кратные 16) обязаны находиться — это проверка зондирования, а не «повезло с хешем»; - после 100 000 вставок `capacity()` растёт (степень двойки, загрузка ≤ 0.7), а `size()` честно считает элементы, включая обновления существующих ключей; - удаление должно работать: после `erase` ключ не находится, а поиск другого ключа, стоявшего за ним в цепочке зондирования, по-прежнему работает. Проверка: `python3 grade.py 10`. Критерий: все `ok`, сборка без предупреждений, ASAN/UBSAN чистые. Разбор после сдачи: почему ёмкость — степень двойки; чем линейное зондирование лучше цепочек по кэшу и хуже по кластеризации; как tombstone-метки спасают поиск после удаления.