You are given an array receiver where receiver[i] is the person who player i passes the ball to. You play a game for k passes. The score of a game starting at player x is the sum of the indices of all players who touch the ball during the k passes (including the starting player). Your goal is to find a starting player that maximizes this total score.
This is a Hard-level Graph problem that tests Binary Lifting (also known as the Successor Graph pattern). Because k can be astronomically large (up to ), simulating the passes step-by-step will immediately Time Limit Exceed. Interviewers ask this to see if you know how to precompute jumps in powers of 2 to traverse massive graphs in time.
The definitive pattern is Binary Lifting.
Since every node has exactly one outgoing edge, the graph is a "functional graph".
We build a 2D table up[node][j], which stores the player who ends up with the ball after passes starting from node. We build a parallel table sum[node][j], which stores the sum of player indices encountered during those passes.
To find the score for k passes, we break k down into its binary representation. If the -th bit of k is 1, we add sum[current_node][j] to our total score, and jump our current_node to up[current_node][j].
Players: 0 passes to 1, 1 passes to 2, 2 passes to 0. k = 3.
The binary representation of 3 is 11 (which is , or 2 passes + 1 pass).
If we start at node 1:
Candidates frequently try to detect cycles in the graph to optimize the math. While cycle detection works conceptually, implementing cycle extraction, calculating the sum of a full cycle, multiplying by k / cycle_length, and adding the remainder is notoriously bug-prone and messy. Binary Lifting is mathematically much cleaner and easier to write under interview pressure.
If you encounter a graph problem where a single pointer moves millions or billions of steps along directed edges (out-degree = 1), Binary Lifting is the required tool. Practice initializing the up[node][0] base cases, and then building the table using the recurrence: up[node][j] = up[ up[node][j-1] ][j-1]. It's the exact same logic used for finding the Lowest Common Ancestor in time.
| Title | Difficulty | Topics | LeetCode |
|---|---|---|---|
| Find the Maximum Sequence Value of Array | Hard | Solve | |
| Make the XOR of All Segments Equal to Zero | Hard | Solve | |
| Maximum Total Reward Using Operations II | Hard | Solve | |
| Bitwise ORs of Subarrays | Medium | Solve | |
| Concatenated Divisibility | Hard | Solve |