<?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=178.66.82.118&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=178.66.82.118&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/178.66.82.118"/>
		<updated>2026-05-19T17:59:55Z</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=22452</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=22452"/>
				<updated>2012-05-17T15:18:22Z</updated>
		
		<summary type="html">&lt;p&gt;178.66.82.118: /* Построение дерева */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition= '''Дерево отрезков''' {{---}} это структура данных, которая позволяет за асимптотику &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; реализовать любые операции, определяемые на [[Моноид | моноиде]]. Например, следующего вида: нахождение суммы (задача RSQ), минимума или максимума (задача RMQ) элементов массива в заданном отрезке (&amp;lt;tex&amp;gt;a[i...j]&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; поступают на вход алгоритма).}}При этом дополнительно возможно изменение элементов массива: как изменение значения одного элемента, так и [[Несогласованные поддеревья. Реализация массового обновления | изменение элементов на целом подотрезке массива]], например разрешается присвоить всем элементам &amp;lt;tex&amp;gt;a[i...j]&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;
Структура представляет собой дерево, листьями которого являются элементы исходного массива. Другие вершины этого дерева имеют по 2 ребёнка и содержат сумму или минимум/максимум своих детей (в зависимости от поставленной задачи вершины могут содержать многие другие операции). Таким образом, корень содержит результат искомой функции от всего массива &amp;lt;tex&amp;gt;[0...n-1]&amp;lt;/tex&amp;gt;, левый ребёнок корня содержит результат функции на &amp;lt;tex&amp;gt;[0...n/2]&amp;lt;/tex&amp;gt;, а правый, соответственно результат на &amp;lt;tex&amp;gt;[n/2+1...n-1]&amp;lt;/tex&amp;gt;. И так далее, продвигаясь вглубь дерева.&lt;br /&gt;
&lt;br /&gt;
==Построение дерева==&lt;br /&gt;
[[Файл:Segment_tree.jpg|right|380px|thumb|Пример дерева отрезков для вычисления сумм]]Пусть исходный массив &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 \ge 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+n/2+n/4...+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;
Далее будем считать, что дерево выстраиваем для задачи вычисления суммы на отрезке. Для минимума и максимума операция построения проделывается аналогично.&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;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;, переменной &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, обозначающей номер элемента в массиве &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, а так же переменные &amp;lt;tex&amp;gt;tl&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;tr&amp;lt;/tex&amp;gt;, обозначающие границы текущего полуинтервала. Запускаем процедуру построения от корня дерева отрезков (&amp;lt;tex&amp;gt;i=0&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;tl=0&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;tr=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;
&lt;br /&gt;
 TreeBuild(a[], i, tl, tr)&lt;br /&gt;
  if (tl = tr) 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; //середина отрезка&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] = f(t[2*i+1], t[2*i+2]);&lt;br /&gt;
&lt;br /&gt;
Выделяют два основных способа построения дерева отрезков: построение снизу и построение сверху. При построении [[Реализация запроса в дереве отрезков снизу | снизу]] алгоритм поднимается от листьев к корню, а при построении [[Реализация запроса в дереве отрезков сверху | сверху]] спускается от корня к листьям, как указано в реализации. Особенные изменения появляются в реализации запросов к таким деревьям отрезков.&lt;br /&gt;
&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;/div&gt;</summary>
		<author><name>178.66.82.118</name></author>	</entry>

	<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=22451</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=22451"/>
				<updated>2012-05-17T15:15:55Z</updated>
		
		<summary type="html">&lt;p&gt;178.66.82.118: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition= '''Дерево отрезков''' {{---}} это структура данных, которая позволяет за асимптотику &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; реализовать любые операции, определяемые на [[Моноид | моноиде]]. Например, следующего вида: нахождение суммы (задача RSQ), минимума или максимума (задача RMQ) элементов массива в заданном отрезке (&amp;lt;tex&amp;gt;a[i...j]&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; поступают на вход алгоритма).}}При этом дополнительно возможно изменение элементов массива: как изменение значения одного элемента, так и [[Несогласованные поддеревья. Реализация массового обновления | изменение элементов на целом подотрезке массива]], например разрешается присвоить всем элементам &amp;lt;tex&amp;gt;a[i...j]&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;
Структура представляет собой дерево, листьями которого являются элементы исходного массива. Другие вершины этого дерева имеют по 2 ребёнка и содержат сумму или минимум/максимум своих детей (в зависимости от поставленной задачи вершины могут содержать многие другие операции). Таким образом, корень содержит результат искомой функции от всего массива &amp;lt;tex&amp;gt;[0...n-1]&amp;lt;/tex&amp;gt;, левый ребёнок корня содержит результат функции на &amp;lt;tex&amp;gt;[0...n/2]&amp;lt;/tex&amp;gt;, а правый, соответственно результат на &amp;lt;tex&amp;gt;[n/2+1...n-1]&amp;lt;/tex&amp;gt;. И так далее, продвигаясь вглубь дерева.&lt;br /&gt;
&lt;br /&gt;
==Построение дерева==&lt;br /&gt;
[[Файл:Segment_tree.jpg|right|380px|thumb|Пример дерева отрезков для вычисления сумм]]Пусть исходный массив &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 \ge 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+n/2+n/4...+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;
Далее будем считать, что дерево выстраиваем для задачи вычисления суммы на отрезке. Для минимума и максимума операция построения проделывается аналогично.&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&amp;lt;/tex&amp;gt; и элемента с номером &amp;lt;tex&amp;gt;2i+1&amp;lt;/tex&amp;gt;, т.е. родитель являлся бы суммой своих сыновей. Лучше всего эту процедуру делать рекурсивно. Создадим функцию от исходного массива &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;, переменной &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, обозначающей номер элемента в массиве &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, а так же переменные &amp;lt;tex&amp;gt;tl&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;tr&amp;lt;/tex&amp;gt;, обозначающие границы текущего полуинтервала. Запускаем процедуру построения от корня дерева отрезков (&amp;lt;tex&amp;gt;i=1&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;tl=0&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;tr=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;
&lt;br /&gt;
 TreeBuild(a[], i, tl, tr)&lt;br /&gt;
  if (tl = tr) 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; //середина отрезка&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] = f(t[2*i+1], t[2*i+2]);&lt;br /&gt;
&lt;br /&gt;
Выделяют два основных способа построения дерева отрезков: построение снизу и построение сверху. При построении [[Реализация запроса в дереве отрезков снизу | снизу]] алгоритм поднимается от листьев к корню, а при построении [[Реализация запроса в дереве отрезков сверху | сверху]] спускается от корня к листьям, как указано в реализации. Особенные изменения появляются в реализации запросов к таким деревьям отрезков.&lt;br /&gt;
&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;/div&gt;</summary>
		<author><name>178.66.82.118</name></author>	</entry>

	<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=22450</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=22450"/>
				<updated>2012-05-17T15:12:14Z</updated>
		
		<summary type="html">&lt;p&gt;178.66.82.118: /* Построение дерева */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition= '''Дерево отрезков''' {{---}} это структура данных, которая позволяет за асимптотику &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; реализовать любые операции, определяемые на [[Моноид | моноиде]]. Например, следующего вида: нахождение суммы (задача RSQ), минимума или максимума (задача RMQ) элементов массива в заданном отрезке (&amp;lt;tex&amp;gt;a[i...j]&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; поступают на вход алгоритма).}}При этом дополнительно возможно изменение элементов массива: как изменение значения одного элемента, так и изменение элементов на целом подотрезке массива, т.е. разрешается присвоить всем элементам &amp;lt;tex&amp;gt;a[i...j]&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;
Структура представляет собой дерево, листьями которого являются элементы исходного массива. Другие вершины этого дерева имеют по 2 ребёнка и содержат сумму или минимум/максимум своих детей (в зависимости от поставленной задачи вершины могут содержать многие другие операции). Таким образом, корень содержит результат искомой функции от всего массива &amp;lt;tex&amp;gt;[0...n-1]&amp;lt;/tex&amp;gt;, левый ребёнок корня содержит результат функции на &amp;lt;tex&amp;gt;[0...n/2]&amp;lt;/tex&amp;gt;, а правый, соответственно результат на &amp;lt;tex&amp;gt;[n/2+1...n-1]&amp;lt;/tex&amp;gt;. И так далее, продвигаясь вглубь дерева.&lt;br /&gt;
&lt;br /&gt;
==Построение дерева==&lt;br /&gt;
[[Файл:Segment_tree.jpg|right|380px|thumb|Пример дерева отрезков для вычисления сумм]]Пусть исходный массив &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 \ge 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+n/2+n/4...+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;
Далее будем считать, что дерево выстраиваем для задачи вычисления суммы на отрезке. Для минимума и максимума операция построения проделывается аналогично.&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&amp;lt;/tex&amp;gt; и элемента с номером &amp;lt;tex&amp;gt;2i+1&amp;lt;/tex&amp;gt;, т.е. родитель являлся бы суммой своих сыновей. Лучше всего эту процедуру делать рекурсивно. Создадим функцию от исходного массива &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;, переменной &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, обозначающей номер элемента в массиве &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, а так же переменные &amp;lt;tex&amp;gt;tl&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;tr&amp;lt;/tex&amp;gt;, обозначающие границы текущего полуинтервала. Запускаем процедуру построения от корня дерева отрезков (&amp;lt;tex&amp;gt;i=1&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;tl=0&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;tr=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;
&lt;br /&gt;
 TreeBuild(a[], i, tl, tr)&lt;br /&gt;
  if (tl = tr) 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; //середина отрезка&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] = f(t[2*i+1], t[2*i+2]);&lt;br /&gt;
&lt;br /&gt;
Выделяют два основных способа построения дерева отрезков: построение снизу и построение сверху. При построении [[Реализация запроса в дереве отрезков снизу | снизу]] алгоритм поднимается от листьев к корню, а при построении [[Реализация запроса в дереве отрезков сверху | сверху]] спускается от корня к листьям, как указано в реализации. Особенные изменения появляются в реализации запросов к таким деревьям отрезков.&lt;br /&gt;
&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;/div&gt;</summary>
		<author><name>178.66.82.118</name></author>	</entry>

	<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=22449</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=22449"/>
				<updated>2012-05-17T15:10:51Z</updated>
		
		<summary type="html">&lt;p&gt;178.66.82.118: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition= '''Дерево отрезков''' {{---}} это структура данных, которая позволяет за асимптотику &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; реализовать любые операции, определяемые на [[Моноид | моноиде]]. Например, следующего вида: нахождение суммы (задача RSQ), минимума или максимума (задача RMQ) элементов массива в заданном отрезке (&amp;lt;tex&amp;gt;a[i...j]&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; поступают на вход алгоритма).}}При этом дополнительно возможно изменение элементов массива: как изменение значения одного элемента, так и изменение элементов на целом подотрезке массива, т.е. разрешается присвоить всем элементам &amp;lt;tex&amp;gt;a[i...j]&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;
Структура представляет собой дерево, листьями которого являются элементы исходного массива. Другие вершины этого дерева имеют по 2 ребёнка и содержат сумму или минимум/максимум своих детей (в зависимости от поставленной задачи вершины могут содержать многие другие операции). Таким образом, корень содержит результат искомой функции от всего массива &amp;lt;tex&amp;gt;[0...n-1]&amp;lt;/tex&amp;gt;, левый ребёнок корня содержит результат функции на &amp;lt;tex&amp;gt;[0...n/2]&amp;lt;/tex&amp;gt;, а правый, соответственно результат на &amp;lt;tex&amp;gt;[n/2+1...n-1]&amp;lt;/tex&amp;gt;. И так далее, продвигаясь вглубь дерева.&lt;br /&gt;
&lt;br /&gt;
==Построение дерева==&lt;br /&gt;
[[Файл:Segment_tree.jpg|right|380px|thumb|Пример дерева отрезков для вычисления сумм]]Пусть исходный массив &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 \ge 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+n/2+n/4...+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;
Далее будем считать, что дерево выстраиваем для задачи вычисления суммы на отрезке. Для минимума и максимума операция построения проделывается аналогично.&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&amp;lt;/tex&amp;gt; и элемента с номером &amp;lt;tex&amp;gt;2i+1&amp;lt;/tex&amp;gt;, т.е. родитель являлся бы суммой своих сыновей. Лучше всего эту процедуру делать рекурсивно. Создадим функцию от исходного массива &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;, переменной &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, обозначающей номер элемента в массиве &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, а так же переменные &amp;lt;tex&amp;gt;tl&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;tr&amp;lt;/tex&amp;gt;, обозначающие границы текущего полуинтервала. Запускаем процедуру построения от корня дерева отрезков (&amp;lt;tex&amp;gt;i=1&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;tl=0&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;tr=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;
&lt;br /&gt;
 TreeBuild(a[], i, tl, tr)&lt;br /&gt;
  if (tl = tr) 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; //середина отрезка&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] = f(t[2*i+1], t[2*i+2]);&lt;br /&gt;
&lt;br /&gt;
Выделяют два основных способа построения дерева отрезков: построение снизу и построение сверху. При построении [[Реализация запроса в дереве отрезков снизу | снизу]] алгоритм поднимается от листьев к корню, как в [[Задача о паросочетании максимального веса в дереве, амортизированные оценки для ДП на дереве  | динамике по поддереву]], а при построении [[Реализация запроса в дереве отрезков сверху | сверху]] спускается от корня к листьям, как указано в реализации. Особенные изменения появляются в реализации запросов к таким деревьям отрезков.&lt;br /&gt;
&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;/div&gt;</summary>
		<author><name>178.66.82.118</name></author>	</entry>

	</feed>