Hi, everyone!
Today I want to present my novel idea of finding $$$LCA$$$ of two nodes in at most $$$O(N + \sum_{j=1}^{Q} \log_2(\max(\text{depth}_{u_j}, \text{depth}_{v_j}) + 1))$$$ in offline. As we can see, algorithm depends heavily on the depth of queries, so in random trees it might work faster and memory is also pure $$$O(N + Q)$$$.
Prerequisites
- Euler tour technique
- Basic binary search
- Understanding tree
From the time complexity and prerequisites you might have guessed that we use ancestors of nodes, it is correct! Using properties of DFS we can keep ancestors sorted by depth in $$$O(N)$$$, example pseudocode:
dfs(v):
ancestors.add(v)
for u in a[v]: dfs(u)
ancestors.pop()
This is true because the moment we finished the subtree of $$$v$$$ node, we no longer can have it as a ancestor for other nodes. Since it is always sorted by depth, which is what we need for our binary search. Our task transforms into finding right-most node in our ancestors, which is ancestor of both $$$u$$$ and $$$v$$$. However we don't need out-order to check, because if current query's node partner was already visited in our DFS, then we can find LCA using only in-order.
Verified code on a problem: https://cses.fi/problemset/task/1688/
Thanks for reading, I hope you have a nice day.








