Блог пользователя Urbanowicz

Автор Urbanowicz, 13 лет назад, По-русски
Пусть у нас есть массив из N элементов, и мы хотим вычислить значение некого ассоциативного оператора над элементами этого массива от L до R включительно. Как известно, если построить дерево отрезков для массива, то мы сможем вычислять это значение за O(log N).

Дерево отрезков — это бинарное дерево, в котором каждой вершине соответствует какой-то отрезок массива, причем родительская вершина покрывает оба отрезка своих сыновей, а их отрезки в свою очередь не пересекаются; корень соответствует всему массиву целиком.

К чему я это говорю. Однажды я захотел поискать какие-нибудь англоязычные описания/реализации дерева отрезков и не смог найти ничего, что было бы предназначено для решения задачи, о которой я говорил в начале. Искал по словам «segment tree» и «interval tree». Если посмотреть статьи с этими названиями на английской Википедии, то мы обнаружим, что эти деревья используются для быстрого нахождения множества отрезков, которым принадлежит заданная точка. То есть задача совсем другая (или я просто не втыкаю, что это одно и то же).

И вот у меня вопрос. Как же по-английски называется та структура данных, которую мы называем деревом отрезков?
  • Проголосовать: нравится
  • +3
  • Проголосовать: не нравится

13 лет назад, # |
Rev. 4   Проголосовать: нравится 0 Проголосовать: не нравится
Ну, вот, на Топкодере что-то такое называется sparse table. Хотя, это не совсем то же самое.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Не, разреженные таблицы - это другой алгоритм, который даже деревом не является. А вот segment tree, который идет там ниже - это уже оно.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Меня чуть-чуть смущает, что автор этой статьи из Румынии (в смысле, его родной язык не английский).

      Он действительно понимает под segment tree то, что надо, но в Википедии-то совсем что-то не то — там вообще ни слова про вычисление или модификацию на отрезке.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Sparse tables не подходят по всем параметрам: занимают n log n места, отвечают на запрос за константу и, самое главное, могут вычислить только идемпотентный оператор.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Видимо, всё же <i>Segment trees</i>.
    Пруф. Статья та же, но надо промотать чуть ниже.

    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Повторю:

      Меня чуть-чуть смущает, что автор этой статьи из Румынии (в смысле, его родной язык не английский).

      Он действительно понимает под segment tree то, что надо, но в Википедии-то совсем что-то не то — там вообще ни слова про вычисление или модификацию на отрезке.
      • 13 лет назад, # ^ |
        Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

        Если я не баран, то в русском языке деревом отрезков называется немного другое -- когда ты можешь отвечать на вопрос "сколько интервалов покрывает заданную точку". Это частный случай того, что ты описал, где единственная разрешенная операция -- это прибавить единицу к интервалу.

        Понятно, что алгоритм расширяется на любой ассоциативный оператор.

        В таком виде (отвечая только на вопрос сколько отрезков пересекает точку) это называется на английском interval tree.

         

        • 13 лет назад, # ^ |
          Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
          Из статьи про interval tree:

          «Interval trees are dynamic, i.e., they allow to insert or delete intervals.
          ...
          If after deleting an interval from the tree, the node containing that interval contains no more intervals, that node may be deleted from the tree»

          По-моему то, что там описано, нифига не расширяется на модификации отрезков массива и к тому же не является статической структурой. По-моему.

          А Иванов Макс видимо вводит нас всех в заблуждение :) И статья называется деревом отрезков, и в URL написано segment_tree.
    • 13 лет назад, # ^ |
      Rev. 3   Проголосовать: нравится +1 Проголосовать: не нравится

      Мда, спать мне надо по ночам а не по инетам ползать %)

      Вот еще такое же виденье segment trees, хотя родной язык автора тоже вызывает сомнения =)

      UPD: А еще если в википедии заменить абстрактные pi на человеческие половинки на целых числах и не хранить всякое барахло в узлах, то оно и выйдет.

      UPD2: Во, и note в вики на эту тему есть:

      Another plus of the segment tree, is that it can easily be adapted to counting queries; that is, report the number of segments containing a given point, instead of reporting the segments themselves. Instead of storing the intervals in the canonical subsets, it can simply be stored an integer representing their amount. Such a segment tree uses linear storage, and requires an O(log n) query time, so it is optimal.

13 лет назад, # |
Rev. 2   Проголосовать: нравится +12 Проголосовать: не нравится

Переписал статью про дерево отрезков.

http://e-maxx.ru/algo/segment_tree

Постарался покрыть все известные мне приложения. Статья в альфа-версии, так что любые замечания приветствуются. Особенно хочется услышать про те применения дерева отрезков, которые я забыл упомянуть.


И да, чуть позже я повешу оглавление на статью, а то в ней легко заблудиться - стандартные h1/h2/h3 здесь плохо работают :)

  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Отлично, но вот самые первые функции build, sum и update можно было сделать нерекурсивными, да и к тому же более короткими и быстрыми.