Сегментное дерево: от теории до практики

Revision ru1, by Sunb1m, 2025-03-19 12:32:58

Теоретическая база

Если вы давно решаете задачи Div1-Div2 на Codeforces, то наверняка уже слышали про сегментное дерево. Звучит возможно для кого-то страшно и не понятно, но на деле это очень полезная структура данных. Проще говоря, сегментное дерево — это такое бинарное дерево, в узлах которого хранятся агрегированные данные о каком-то отрезке массива. За счёт этой древовидной структуры мы можем быстро отвечать на запросы о произвольных сегментах массива да и не только отвечать, но и обновлять элементы.

Представьте, что у нас есть массив, и требуется многократно узнавать что-то про подотрезки этого массива, например, сумму элементов, минимум, максимум, количество каких-то значений и т.д. Сегментное дерево позволяет делать такие запросы очень быстро — обычно за O(log n) на каждый запрос вместо тривиального O(n) перебора. При этом оно достаточно гибкое, поддерживает изменение отдельных элементов, а с дополнительными трюками (ленивые пропагации) может даже массово обновлять целые диапазоны за то же логарифмическое время​. В общем, сегментник может довольно хорошо оптимизировать алгоритм программы, когда обычных массивов и сортировок уже не хватает.

Пример сегментного дерева, построенного для массива arr = {1, 3, 5, 7, 9, 11}. Каждый узел хранит сумму на соответствующем отрезке: корень содержит 36 (сумма на всём отрезке [0;5]), его дети – суммы на [0;2] и [3;5] (9 и 27) и так далее.

Как это работает?

Tags структуры данных, алгоритмы

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
ru17 Russian Sunb1m 2025-03-19 21:28:22 7 Мелкая правка: 'я слишком медленно\n\nДерев' -> 'я слишком долго\n\nДерев'
ru16 Russian Sunb1m 2025-03-19 21:27:38 2 Мелкая правка: ', когда:\n1. Нужно' -> ', когда:\n\n1. Нужно'
ru15 Russian Sunb1m 2025-03-19 17:31:42 445
en4 English Sunb1m 2025-03-19 14:37:05 4
ru14 Russian Sunb1m 2025-03-19 14:18:48 8 Мелкая правка: 'егментник — must know' -> 'егментник must know'
en3 English Sunb1m 2025-03-19 14:14:25 117
ru13 Russian Sunb1m 2025-03-19 14:14:10 104
en2 English Sunb1m 2025-03-19 14:12:52 71
ru12 Russian Sunb1m 2025-03-19 14:12:29 65
ru11 Russian Sunb1m 2025-03-19 14:07:45 0 (опубликовано)
en1 English Sunb1m 2025-03-19 14:07:27 8124 Initial revision for English translation
ru10 Russian Sunb1m 2025-03-19 13:57:09 2
ru9 Russian Sunb1m 2025-03-19 13:56:44 2 Мелкая правка: 'пераций:\n- Диапаз' -> 'пераций:\n\n- Диапаз'
ru8 Russian Sunb1m 2025-03-19 13:54:45 3222
ru7 Russian Sunb1m 2025-03-19 13:31:12 4
ru6 Russian Sunb1m 2025-03-19 13:30:59 1717
ru5 Russian Sunb1m 2025-03-19 12:59:21 205
ru4 Russian Sunb1m 2025-03-19 12:42:55 693
ru3 Russian Sunb1m 2025-03-19 12:38:56 1014
ru2 Russian Sunb1m 2025-03-19 12:34:06 2
ru1 Russian Sunb1m 2025-03-19 12:32:58 1545 Первая редакция (сохранено в черновиках)