Design mutable sum-tree with fast queries
Company: Airbnb
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates proficiency in designing dynamic data structures for mutable rooted trees, including maintenance of subtree sums, parent/child link management, and analysis of update and query complexities within the Coding & Algorithms domain; it emphasizes practical application of algorithmic design coupled with conceptual understanding of invariants and amortized complexity. It is commonly asked in technical interviews because it probes reasoning about correctness and performance under mutations, handling edge cases such as subtree deletion and reattachment, and the ability to specify algorithmic approaches and complexity guarantees rather than implementation details.
Constraints
- The initial structure is a valid rooted tree.
- 1 <= total number of nodes that ever appear across the whole input <= 2 * 10^5.
- -10^9 <= each leaf value <= 10^9, and sums may exceed 32-bit range.
- Operations are valid: `get` and `toLeaf` reference existing nodes, `toParent` is called on a current leaf, and added node ids are not currently present in the tree.
- If `toParent(nodeId, [], {})` is used, `nodeId` becomes an internal node with no children and value 0.
Examples
Input: ([(1, 2), (1, 3), (3, 4), (3, 5)], {2: 5, 4: 2, 5: 1}, [('get', 1), ('get', 3), ('toLeaf', 3, 10), ('get', 1), ('get', 3), ('toParent', 2, [(2, 6), (2, 7)], {6: 4, 7: -1}), ('get', 2), ('get', 1)])
Expected Output: [8, 3, 15, 10, 3, 13]
Explanation: Initially node 3 = 2 + 1 = 3 and node 1 = 5 + 3 = 8. After making node 3 a leaf with value 10, node 1 becomes 15. Then node 2 changes from leaf 5 to an internal node with children 6 and 7, so node 2 = 4 + (-1) = 3 and node 1 becomes 13.
Input: ([], {1: 7}, [('get', 1), ('toParent', 1, [], {}), ('get', 1), ('toLeaf', 1, -3), ('get', 1)])
Expected Output: [7, 0, -3]
Explanation: Single-node tree edge case. The empty `toParent` makes node 1 an internal node with no children, so its sum is 0. Converting it back to a leaf with value -3 updates the node correctly.
Hints
- Store each node's current subtree sum so a `get` query can be answered in O(1).
- After a mutation, only the changed node, any added/removed subtree nodes, and the node's ancestors are affected. Propagate a delta upward through parent pointers instead of recomputing the whole tree.