Problem Description
Given a tree with n nodes (labeled 0 to n–1) where node 0 is the root, each node has an integer value. The subtree of a node is defined as the node itself plus all its descendants. We want to choose two subtrees that do not share any common node and maximize the score defined as the bitwise XOR of the sum of values in the two subtrees. If no two non‐overlapping subtrees exist, we must return 0.
Key Insights
- First, compute for each node its subtree sum using a DFS.
- Use an Euler tour (recording tin and tout for every node) so that the subtree of a node appears as a contiguous interval.
- Two subtrees (with roots u and v) are non-overlapping if and only if their Euler intervals do not intersect; equivalently, either tout[u] < tin[v] or tout[v] < tin[u].
- Thus, if we sort nodes by tin, for a fixed node i the “left” valid partners are those earlier in the tin‐ordering (j < i) that satisfy tout[j] < tin[i], and the “right” valid partners are those with index j whose tin is greater than the current node’s tout.
- For fast maximum XOR queries, use a Trie (bitwise trie) where each inserted number is represented in binary.
- Because the valid partner set “changes” depending on the current node’s Euler indices, the solution splits into two parts: • A left‐pass: iterate in tin order while “adding” nodes that “end” (i.e. their tout is before the current node’s tin). • A right–pass: for a given node, the valid right candidates are those whose tin index is larger than the current node’s tout. This can be supported by building a persistent (or segment‑tree based) Trie keyed on the Euler ordering.
- The final answer is the maximum of the XOR between the current node’s subtree sum and a valid candidate’s subtree sum from either left or right.
Space and Time Complexity
Time Complexity: O(n · B) where B is the number of bits (roughly 32) – each DFS + trie insertion/query is O(32). Space Complexity: O(n · B) for storing subtree information and the trie nodes.
Solution
We start by performing a DFS from the root to compute three values for each node: • subtreeSum – the sum of values in the subtree rooted at that node. • tin – the time when we first visit the node. • tout – the time when we finish processing the node. Because the DFS Euler tour order yields that the subtree of a node corresponds to a contiguous range [tin, tout], two subtrees (with roots u and v) are non-overlapping if either tout[u] < tin[v] or tout[v] < tin[u].
The idea is to precompute an array "nodes" sorted by tin. Then, in a left–pass we maintain a Trie that only contains those nodes (already processed) whose tout is less than the current node’s tin (ensuring they are not ancestors). We query the Trie with the current node’s subtree sum to get the best XOR candidate.
Similarly, in a right–pass we need to quickly query nodes that come “after” the current node’s Euler interval, i.e. nodes with tin > current node’s tout. This is achieved by building a persistent Trie (or an offline segment tree of Tries) indexed by the tin order so that for any index L we can query the “suffix” Trie built from nodes in positions L..n–1.
The solution uses standard bit–trie operations (insert and query) performed on 32–bit representations. The “gotcha” is to pay close attention when adding a candidate to the Trie: only those nodes with Euler tout less than the current node’s tin (or, for the right–pass, only those with tin > current node’s tout) are valid.
Below are code solutions in several languages with clear line–by–line commentary.