Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions content/russian/cs/range-queries/sqrt-structures.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ authors:
- Сергей Слотин
- Иван Сафонов
weight: 6
date: 2022-08-16
date: 2022-08-16T00:00:00.000Z
---

Корневые оптимизации можно использовать много для чего, в частности в контексте структур данных.
Expand Down Expand Up @@ -119,8 +119,8 @@ pair<int, int> find_block(int pos) {

Решение в таком виде будет хорошо работать только первое время, когда каждая операция будет просматривать не более $O(\sqrt n)$ блоков и не более $O(\sqrt n)$ элементов по отдельности, но с течением времени может получиться, что либо блоков слишком много, либо есть слишком большие блоки. Есть два способа решать эту проблему:

1. После каждой операции добавления или удаления смотреть на затронутый блок, и если его размер больше $2 \cdot \sqrt n$, то разделять его на два, а также если он и его сосед в сумме дают меньше $n$, то смерджить их в один.
2. Завести глобальный счетчик операций и просто перестраивать целую структуру каждые $\sqrt q$ запросов (выписать обратно в массив и заново разделить на равные блоки).
1. **split-merge**: После каждой операции добавления или удаления смотреть на затронутый блок, и если его размер больше $2 \cdot \sqrt n$, то разделять его на два, а также если он и его сосед в сумме дают меньше $\sqrt n$, то объединить их в один.
2. **split-rebuild**: Завести глобальный счетчик операций и просто перестраивать целую структуру каждые $\sqrt q$ запросов (выписать обратно в массив и заново разделить на равные блоки).

В первом случае мы потенциально тратим $O(\sqrt n)$ операций на сплиты и мерджи, но гарантируем инварианты, а во втором получаем ровно $\sqrt n$ помножить на стоимость построения.

Expand Down