День 1. RMQ & LCA
- С/C++:
#define _GLIBCXX_DEBUG
, vector-а, никаких глобальных переменных, struct SparseTable
- RMQ: Формулировка. Простые решение: [O(n2), O(1)] и [O(n), O(n)], деревом отрезков за [O(n), O(logn)]
- RMQ: Sparse table: [nlogn, 1], [n, loglogn], [nlog*n, log*n]
- RMQ±1 за [n, 1]
- LCA: Формулирова. Решение за O(distance).
- LCA: Двоичные подъёмы [nlogn, logn]
- LCA → RMQ±1 за O(n), итого решение LCA за [O(n), O(1)] (Эйлеров обход)
- Эйлеров обход − функция на поддереве это теперь функция на отрезке
- RMQ → LCA за O(n) (построение декартова дерева за O(n2) и O(n)), итого RMQ за [O(n), O(1)]
- LCA в Offline за O((n+m)*) (алгоритм Ахо-Ульмана-Тарьяна)
- Функция на пути в статичном дереве: online = двоичные подъёмы
- Обратимая ассоциативная функция на пути в статичном дереве за [O(n), O(1)]