From e1b47a3e2702e9b5668fb73c0aa0d8e7ca4e1fb3 Mon Sep 17 00:00:00 2001 From: Petrov Egor Date: Sat, 10 Jan 2026 21:28:44 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=B2=D0=B8=D0=B6=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D1=8B?= =?UTF-8?q?:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BE?= =?UTF-8?q?=D1=88=D0=B8=D0=B1=D0=BA=D1=83,=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D1=87=D0=B0=D1=81=D1=82=D1=8B=D0=B5=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BC=D0=B5?= =?UTF-8?q?=D1=82=D0=BE=D0=B4=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/russian/cs/range-queries/sqrt-structures.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/russian/cs/range-queries/sqrt-structures.md b/content/russian/cs/range-queries/sqrt-structures.md index 25fe3b5e..373da4c0 100644 --- a/content/russian/cs/range-queries/sqrt-structures.md +++ b/content/russian/cs/range-queries/sqrt-structures.md @@ -4,7 +4,7 @@ authors: - Сергей Слотин - Иван Сафонов weight: 6 -date: 2022-08-16 +date: 2022-08-16T00:00:00.000Z --- Корневые оптимизации можно использовать много для чего, в частности в контексте структур данных. @@ -119,8 +119,8 @@ pair 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$ помножить на стоимость построения.