Problem Description
Given a tree with n nodes (from 0 to n - 1) represented by a parent array, implement a class that can quickly return the kth ancestor of any given node. The kth ancestor is the kth node in the path from the node to the root. If no such ancestor exists, return -1.
Key Insights
- Precompute ancestors using Binary Lifting to answer kth ancestor queries in O(log n) time.
- Use a 2D array (or table) where dp[node][j] represents the 2^j-th ancestor of the node.
- Precompute the table for all nodes in O(n log n) time.
- Each query is then answered by decomposing k into powers of two and lifting the node up accordingly.
- This approach is efficient given the constraints (up to 50000 nodes and queries).
Space and Time Complexity
Time Complexity:
- Preprocessing: O(n log n)
- Each query: O(log n) Space Complexity: O(n log n) for storing the binary lifting table.
Solution
The solution utilizes binary lifting, where we precompute for every node the ancestor at powers of two distances (i.e. 1, 2, 4, 8, ...). During a query for the kth ancestor of a node, we iterate through the bits in the binary representation of k. For each set bit, we move the node pointer to its corresponding ancestor using our precomputed table. If at any point the node becomes -1, we return -1 indicating that the kth ancestor does not exist.