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

Автор slivolymp, история, 6 лет назад, По-русски

Как эффективно обрабатывать запросы вида "Найти сумму элементов, таких что x < a[i] < y на отрезке l < i < r" с изменением в элементе с помощью дерева отрезков?

  • Проголосовать: нравится
  • +18
  • Проголосовать: не нравится

»
6 лет назад, # |
  Проголосовать: нравится -25 Проголосовать: не нравится

ну когда ты строишь дерево отрезков , в функции build там где l==r проверяй если число соответствует твоему условию то t[v]=a[l]; а если нет то t[v]=0;

»
6 лет назад, # |
  Проголосовать: нравится -10 Проголосовать: не нравится

3d Mo

»
6 лет назад, # |
  Проголосовать: нравится +9 Проголосовать: не нравится

Пусть для каждой вершины дерева отрезков мы храним весь ее подотрезок в двоичном сбалансированном дереве (например, в декартовом дереве). Понятно, что для изменения в элементе небодимо обновить этот элемент в отрезках. Теперь рассмотрим запрос суммы. Понятно, что весь отрезок запроса мы можем разбить на отрезков, которые есть в дереве отрезков. Теперь для каждого такого отрезка нам необходимо найти сумму всех элементов, для которых верно x < ai < y. Это легко сделать с помощью двоичного сбалансиванного дерева (дополнительно храним и обновляем сумму на поддереве), в котором хранится весь этот отрезок.

Итого получаем на запрос и на обновление элемента.

  • »
    »
    6 лет назад, # ^ |
      Проголосовать: нравится +11 Проголосовать: не нравится

    Если запросы даны offline, то можно для каждой вершины дерева отрезка найти все значения, которые там будут в какой-либо момент, и сжать их (для каждой вершины свое сжатие). После этого мы можем использовать более "статическую" структуру, например, дерево Фенвика. Запрос будет тоже за O(log2n), но вроде константа бинпоиска (сжатие) + Фенвика меньше, чем у декартова дерева.