<?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=Sphilippov</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=Sphilippov"/>
		<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/Sphilippov"/>
		<updated>2026-05-19T14:16:45Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9C%D0%BD%D0%BE%D0%B3%D0%BE%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%A4%D0%B5%D0%BD%D0%B2%D0%B8%D0%BA%D0%B0&amp;diff=26430</id>
		<title>Многомерное дерево Фенвика</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9C%D0%BD%D0%BE%D0%B3%D0%BE%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%A4%D0%B5%D0%BD%D0%B2%D0%B8%D0%BA%D0%B0&amp;diff=26430"/>
				<updated>2012-06-21T20:58:56Z</updated>
		
		<summary type="html">&lt;p&gt;Sphilippov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Многомерное [[дерево Фенвика]]''' - структура данных, требующая &amp;lt;tex&amp;gt; O(n^k) &amp;lt;/tex&amp;gt; памяти и позволяющая эффективно (за &amp;lt;tex&amp;gt; O(\log^k n) &amp;lt;/tex&amp;gt;)&lt;br /&gt;
# изменять значение любого элемента в k-мерном массиве;&lt;br /&gt;
# выполнять некоторую ассоциативную, коммутативную, обратимую операцию &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; на k-мерном прямоугольнике &amp;lt;tex&amp;gt; [i_1, \ldots ,i_k] &amp;lt;/tex&amp;gt;;&amp;lt;br/&amp;gt; где n - максимальное значение для каждой координаты.&lt;br /&gt;
}}&lt;br /&gt;
Рассмотрим дерево Фенвика на примере k-мерного массива с k = 2, с увеличением k на единицу в операциях будет просто добавляться проход по k+1 измерению. &lt;br /&gt;
&lt;br /&gt;
Пусть дан массив &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt; n \times m &amp;lt;/tex&amp;gt; элементов: &amp;lt;tex&amp;gt; a_{i,j}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Деревом Фенвика будем называть массив &amp;lt;tex&amp;gt; T &amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt; n \times m &amp;lt;/tex&amp;gt; элементов: &amp;lt;tex&amp;gt; T_{i,j} = \sum\limits_{k = F(i)}^{i} \sum\limits_{q = F(j)}^{j}a_{k,q}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; F(i) = i \&amp;amp; (i + 1) &amp;lt;/tex&amp;gt;, как и в одномерном [[дерево Фенвика|дереве Фенвика]].&lt;br /&gt;
&lt;br /&gt;
==Пример задачи для двумерного случая==&lt;br /&gt;
[[Файл:example42.gif |thumb|600px|right|Пример дерева Фенвика &amp;lt;tex&amp;gt;(16 \times 8)&amp;lt;/tex&amp;gt;. Синим обозначены ячейки, которые обновятся при изменении ячейки &amp;lt;tex&amp;gt;(5, 3)&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
Пусть имеем набор точек на плоскости с неотрицательными координатами. Определены 3 операции:&lt;br /&gt;
# добавить точку в &amp;lt;tex&amp;gt;(x, y)&amp;lt;/tex&amp;gt;;&lt;br /&gt;
# удалить точку из &amp;lt;tex&amp;gt;(x, y)&amp;lt;/tex&amp;gt;;&lt;br /&gt;
# посчитать количество точек в прямоугольнике &amp;lt;tex&amp;gt;(0, 0), (x, y)&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - количество точек, &amp;lt;tex&amp;gt;maxX&amp;lt;/tex&amp;gt; - максимальная &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; координата, &amp;lt;tex&amp;gt;maxY&amp;lt;/tex&amp;gt; - максимальная &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt; координата.&amp;lt;br/&amp;gt;&lt;br /&gt;
Тогда дерево строится за &amp;lt;tex&amp;gt;O(n\cdot\log(maxX)\cdot\log(maxY))&amp;lt;/tex&amp;gt;, а запросы выполняются за &amp;lt;tex&amp;gt;O(\log (maxX)\cdot\log (maxY))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Добавляя точку вызовем &amp;lt;tex&amp;gt;inc(x, y, 1)&amp;lt;/tex&amp;gt;, а удаляя &amp;lt;tex&amp;gt;inc(x, y, -1)&amp;lt;/tex&amp;gt;. Таким образом запрос &amp;lt;tex&amp;gt;sum(x, y)&amp;lt;/tex&amp;gt; дает количество точек в прямоугольнике.&lt;br /&gt;
&lt;br /&gt;
''Пример реализации для двумерного случая:''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 vector &amp;lt;vector &amp;lt;int&amp;gt; &amp;gt; t;&lt;br /&gt;
 int n, m;&lt;br /&gt;
 &lt;br /&gt;
 int sum (int x, int y)&lt;br /&gt;
 {&lt;br /&gt;
        int result = 0;&lt;br /&gt;
        for (int i = x; i &amp;gt;= 0; i = (i &amp;amp; (i+1)) - 1)&lt;br /&gt;
           for (int j = y; j &amp;gt;= 0; j = (j &amp;amp; (j+1)) - 1)&lt;br /&gt;
              result += t[i][j];&lt;br /&gt;
        return result;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void inc (int x, int y, int delta)&lt;br /&gt;
 {&lt;br /&gt;
        for (int i = x; i &amp;lt; n; i = (i | (i+1)))&lt;br /&gt;
           for (int j = y; j &amp;lt; m; j = (j | (j+1)))&lt;br /&gt;
              t[i][j] += delta;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы посчитать значение функции для прямоугольника &amp;lt;tex&amp;gt;(x_1, y_1), (x_2, y_2)&amp;lt;/tex&amp;gt; нужно воспользоваться формулой включения-исключения. Например для суммы: &amp;lt;tex&amp;gt;s = sum(x_2,y_2)-sum(x_2,y_1 - 1)-sum(x_1 - 1,y_2)+sum(x_1 - 1,y_1 - 1)&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Файл:ФормулаВключения-Исключения.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Полезные ссылки: ==&lt;br /&gt;
Wikipedia: [http://en.wikipedia.org/wiki/Fenwick_tree Fenwick tree] &amp;lt;br/&amp;gt;&lt;br /&gt;
e-maxx.ru: [http://e-maxx.ru/algo/fenwick_tree Дерево Фенвика] &amp;lt;br/&amp;gt;&lt;br /&gt;
TopCoder:  [http://www.topcoder.com/tc?module=Static&amp;amp;d1=tutorials&amp;amp;d2=binaryIndexedTrees#find Binary Indexed Trees]&lt;/div&gt;</summary>
		<author><name>Sphilippov</name></author>	</entry>

	</feed>