<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=31.181.107.167&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=31.181.107.167&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/31.181.107.167"/>
		<updated>2026-06-14T21:30:49Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2._%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5&amp;diff=68020</id>
		<title>Дерево отрезков. Построение</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2._%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5&amp;diff=68020"/>
				<updated>2018-12-24T17:59:20Z</updated>
		
		<summary type="html">&lt;p&gt;31.181.107.167: Ошибка описания картинки&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Дерево отрезков''' (англ. ''Segment tree'') {{---}} это структура данных, которая позволяет за асимптотику &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; реализовать любые операции, определяемые на множестве, на котором данная операция ассоциативна, и существует нейтральный элемент относительно этой операции, то есть на [[Моноид | моноиде]]. Например, суммирование на множестве натуральных чисел, поиск минимума на любом числовом множестве, перемножение матриц на множестве матриц размера &amp;lt;tex&amp;gt;N*N&amp;lt;/tex&amp;gt;, объединение множеств, поиск наибольшего общего делителя на множестве целых чисел и многочленов.&lt;br /&gt;
&lt;br /&gt;
При этом дополнительно возможно изменение элементов массива: как изменение значения одного элемента, так и [[Несогласованные поддеревья. Реализация массового обновления | изменение элементов на целом подотрезке массива]], например разрешается присвоить всем элементам &amp;lt;tex&amp;gt;a[l \ldots r]&amp;lt;/tex&amp;gt; какое-либо значение, либо прибавить ко всем элементам массива какое-либо число. Структура занимает &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; памяти, а ее построение требует &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; времени. &lt;br /&gt;
&lt;br /&gt;
==Структура==&lt;br /&gt;
Структура представляет собой дерево, листьями которого являются элементы исходного массива. Другие вершины этого дерева имеют по &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; ребенка и содержат результат операции от своих детей (например минимум или сумму). Таким образом, корень содержит результат искомой функции от всего массива &amp;lt;tex&amp;gt;[0\ldots n-1]&amp;lt;/tex&amp;gt;, левый ребёнок корня содержит результат функции на &amp;lt;tex dpi=120&amp;gt;[0\ldots\dfrac{n}{2}]&amp;lt;/tex&amp;gt;, а правый, соответственно результат на &amp;lt;tex dpi=120&amp;gt;[\dfrac{n}{2}+1\ldots n-1]&amp;lt;/tex&amp;gt;. И так далее, продвигаясь вглубь дерева.&lt;br /&gt;
&lt;br /&gt;
==Построение дерева==&lt;br /&gt;
Пусть исходный массив &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; элементов. Для удобства построения увеличим длину массива &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; так, чтобы она равнялась ближайшей степени двойки, т.е. &amp;lt;tex&amp;gt;2^k&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;2^k \geqslant n&amp;lt;/tex&amp;gt;. Это сделано, для того чтобы не допустить обращение к несуществующим элементам массива при дальнейшем процессе построения. Пустые элементы необходимо заполнить нейтральными элементами моноида. Тогда для хранения дерева отрезков понадобится массив &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;  из  &amp;lt;tex&amp;gt;2^{k+1}&amp;lt;/tex&amp;gt; элементов, поскольку в худшем случае количество вершин в дереве можно оценить суммой &amp;lt;tex&amp;gt;n+\dfrac{n}{2}+\dfrac{n}{4} \ldots +1 &amp;lt; 2n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;n=2^k&amp;lt;/tex&amp;gt;. Таким образом, структура занимает линейную память.&lt;br /&gt;
&lt;br /&gt;
Процесс построения дерева заключается в заполнении массива &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Заполним этот массив таким образом, чтобы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-й элемент являлся бы результатом некоторой бинарной операции (для каждой конкретной задачи своей) от элементов c номерами &amp;lt;tex&amp;gt;2i+1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;2i+2&amp;lt;/tex&amp;gt;, то есть родитель являлся результатом бинарной операции от своих сыновей (обозначим в коде эту операцию как  &amp;quot;&amp;lt;tex&amp;gt; \circ &amp;lt;/tex&amp;gt;&amp;quot;). Один из вариантов — делать рекурсивно. Пусть у нас имеются исходный массив &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;,  а также переменные &amp;lt;tex&amp;gt;\mathtt{tl}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathtt{tr}&amp;lt;/tex&amp;gt;, обозначающие границы текущего полуинтервала. Запускаем процедуру построения от корня дерева отрезков (&amp;lt;tex&amp;gt;i=0&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;\mathtt{tl}=0&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;\mathtt{tr}=n&amp;lt;/tex&amp;gt;), а сама процедура построения, если её вызвали не от листа, вызывает себя от каждого из двух сыновей и суммирует вычисленные значения, а если её вызвали от листа — то просто записывает в себя значение этого элемента массива (Для этого у нас есть исходный массив &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;). Асимптотика построения дерева отрезков составит, таким образом, &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выделяют два основных способа построения дерева отрезков: построение снизу и построение сверху. При построении [[Реализация запроса в дереве отрезков снизу | снизу]] алгоритм поднимается от листьев к корню (Просто начинаем заполнять элементы массива &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; от большего индекса к меньшему, таким образом при заполнении элемента &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt; его дети &amp;lt;tex&amp;gt;2i+1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;2i+2&amp;lt;/tex&amp;gt; уже будут заполнены, и мы с легкостью посчитаем бинарную операцию от них), а при построении [[Реализация запроса в дереве отрезков сверху | сверху]] спускается от корня к листьям. Особенные изменения появляются в реализации запросов к таким деревьям отрезков.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Segment_tree.png|Пример дерева отрезков для минимума]]&lt;br /&gt;
&lt;br /&gt;
Реализация построения сверху:&lt;br /&gt;
&lt;br /&gt;
 '''function''' treeBuild('''T''' a[], '''int''' i, '''int''' tl, '''int''' tr):  &amp;lt;font color=green&amp;gt;// мы находимся в вершине с номером i, который отвечает за полуинтервал [tl, tr) &amp;lt;/font&amp;gt;&lt;br /&gt;
     '''if''' tl == tr &lt;br /&gt;
         '''return'''&lt;br /&gt;
     '''if''' tr - tl == 1&lt;br /&gt;
         t[i] = a[tl]&lt;br /&gt;
     '''else'''&lt;br /&gt;
         tm = (tl + tr) / 2                            &amp;lt;font color=green&amp;gt;// середина отрезка&amp;lt;/font&amp;gt;&lt;br /&gt;
         treeBuild(a, 2 * i + 1, tl, tm)&lt;br /&gt;
         treeBuild(a, 2 * i + 2, tm, tr)&lt;br /&gt;
         t[i] = t[2 * i + 1] &amp;lt;tex&amp;gt; \circ &amp;lt;/tex&amp;gt; t[2 * i + 2]&lt;br /&gt;
&lt;br /&gt;
Реализация построения снизу:&lt;br /&gt;
&lt;br /&gt;
 '''function''' treeBuild('''T''' a[]):&lt;br /&gt;
     '''for''' i = 0 '''to''' n - 1&lt;br /&gt;
         t[n - 1 + i] = a[i]&lt;br /&gt;
     '''for''' i = n - 2 '''downto''' 0&lt;br /&gt;
         t[i] = t[2 * i + 1] &amp;lt;tex&amp;gt; \circ &amp;lt;/tex&amp;gt; t[2 * i + 2]&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Реализация запроса в дереве отрезков сверху]]&lt;br /&gt;
&lt;br /&gt;
*[[Реализация запроса в дереве отрезков снизу]]&lt;br /&gt;
&lt;br /&gt;
*[[Несогласованные поддеревья. Реализация массового обновления]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации== &lt;br /&gt;
* [http://habrahabr.ru/post/115026/ Хабрахабр — Статья Максима Ахмедова]&lt;br /&gt;
&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/trees/segment-2006  Дискретная математика: Алгоритмы — Визуализатор дерева отрезков]&lt;br /&gt;
&lt;br /&gt;
* [http://e-maxx.ru/algo/segment_tree  MAXimal :: algo :: Дерево отрезков]&lt;br /&gt;
&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2   Википедия — Дерево отрезков]&lt;br /&gt;
&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/Моноид  Википедия — Моноид]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Дерево отрезков]]&lt;br /&gt;
[[Категория: Структуры данных]]&lt;/div&gt;</summary>
		<author><name>31.181.107.167</name></author>	</entry>

	</feed>