Implement a Referral Revenue Tracker
Company: Uber
Role: Machine Learning Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates proficiency with data structures and algorithms for hierarchical aggregation and ranking, assessing skills such as maintaining recursive subtree aggregates, handling dynamic inserts, and executing efficient top-k queries; it is in the Coding & Algorithms domain and tests practical application of in-memory data structure design. It is commonly asked to evaluate the ability to design scalable, low-latency in-memory systems that preserve aggregate values across referral trees and support fast query operations while reasoning about time and space complexity trade-offs.
Constraints
- 0 <= len(operations) <= 10^4
- There are at most 5000 distinct customers
- 1 <= customer_id <= 10^9
- -10^9 <= amount, threshold <= 10^9
- 0 <= k <= number of current customers
- If a new customer is inserted with a non-None referrer_id, that referrer already exists and the referral graph is acyclic
Examples
Input: [("insert", 1, 100, None), ("insert", 2, 50, 1), ("insert", 3, 70, 1), ("top_k", 2, 100), ("insert", 2, 30, None), ("top_k", 3, 60)]
Expected Output: [[[1, 220]], [[1, 250], [2, 80], [3, 70]]]
Explanation: After the first three inserts, customer 1 has aggregate revenue 220. After adding 30 more to customer 2, customer 2 becomes 80 and customer 1 becomes 250.
Input: [("insert", 1, 50, None), ("insert", 2, 50, None), ("insert", 3, 10, 1), ("insert", 4, 10, 2), ("top_k", 2, 59), ("top_k", 3, 50)]
Expected Output: [[[1, 60], [2, 60]], [[1, 60], [2, 60]]]
Explanation: Customers 1 and 2 both have aggregate revenue 60, so the tie is broken by smaller customer ID first.
Input: [("insert", 1, 100, None), ("insert", 2, -20, 1), ("insert", 3, 50, 2), ("top_k", 3, 200), ("top_k", 3, 20), ("insert", 2, -40, None), ("top_k", 3, 20)]
Expected Output: [[], [[1, 130], [3, 50], [2, 30]], [[1, 90], [3, 50]]]
Explanation: The first query returns no customers because aggregate revenue must be strictly greater than 200. Negative revenue updates reduce both the customer's aggregate and all ancestors' aggregates.
Input: [("insert", 1, 10, None), ("insert", 2, 5, 1), ("insert", 2, 15, 1), ("insert", 3, 7, None), ("insert", 2, 5, 3), ("top_k", 10, 0)]
Expected Output: [[[1, 35], [2, 25], [3, 7]]]
Explanation: Customer 2 already exists when inserted with referrer 3, so its original referrer remains 1. Only the revenue is added.
Input: []
Expected Output: []
Explanation: With no operations, there are no query results.
Hints
- When revenue is added to one customer, the same delta must also be reflected in every ancestor's aggregate revenue.
- For each top_k query, first filter customers whose aggregate revenue is above the threshold, then sort by the required key: descending aggregate revenue and ascending customer ID.