Implementations of LCA and RMQ data structures from "The LCA Problem Revisited"
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.gitignore
CMakeLists.txt
README.md
lca.cpp
lca.hpp
naive_rmq.cpp
naive_rmq.hpp
opt_rmq.cpp
opt_rmq.hpp
pm_rmq.cpp
pm_rmq.hpp
pm_rmq_test.hpp
rmq.hpp
rmq_test.hpp
sparse_rmq.cpp
sparse_rmq.hpp
tree.hpp

README.md

rmq

Implementations of LCA and RMQ data structures from The LCA Problem Revisited.

All implementations take some care to work with generic types, and the code is therefore a bit hard to read, sorry about that.

Generally, iterator types should be RandomAccessIterators, difference types should be signed (they'll be subtracted from one another and compared) and value types should have sensible comparison and equality operators, and for the pm_rmq structure they need a reasonable operator-() so we can normalize sub blocks. The values will also be copied a few times, so avoid huge values if you can.

naive_rmq

Implements the <O(n^2), O(1)> naive RMQ algorithm, where the answers to every possible RMQ query are computed and stored ahead of time.

Warning: the naive implementation uses O(n^2) memory and therefore before running it you should really lower N in rmq_test.hpp to something pretty small (10000 works on an 8GB, 64-bit machine), or you'll run out of memory very quickly.

sparse_rmq

Implements the <O(n * log(n)), O(1)> "Sparse Tree" RMQ algorithm, which improves on the naive algorithm by only storing answers to queries of sizes that are powers of 2.

pm_rmq

Implements the <O(n), O(1)> algorithm for RMQ problems that satisfy the "±1 constraint" that all consecutive elements differ by exactly +1 or -1.

This could use some optimization work. We currently use a std::map and a std::vector where we should really use a statically allocated table with some fancy bit twiddling.

lca

Implements the <O(n), O(1)> algorithm for solving the LCA problem by reduction to the ±1 RMQ problem and using pm_rmq.

opt_rmq

Implements the <O(n), O(1)> algorithm for general RMQ by constructing the Cartesian tree of the input to convert it to an LCA problem, which is then solved in <O(n), O(1)>.