There is a rooted tree consisting of n nodes numbered 0 to n - 1. Each node’s number denotes its unique genetic value (i.e. the genetic value of node x is x). The genetic difference between two genetic values is defined as the **bitwise-**XOR of their values. You are given the integer array parents, where parents[i] is the parent for node i. If node x is the root of the tree, then parents[x] == -1.
You are also given the array queries where queries[i] = [nodei, vali]. For each query i, find the maximum genetic difference between vali and
pi, where pi is the genetic value of any node that is on the path between
nodei and the root (including nodei and the root). More formally, you want to maximize vali XOR pi.
Return an arrayanswhereans[i]is the answer to theithquery.

Input: parents =[-1,0,1,1], queries =[[0,2],[3,2],[2,5]]Output: [2,3,7]Explanation: The queries are processed as follows:-[0,2]: The node with the maximum genetic difference is0,with a difference of 2 XOR 0=2.-[3,2]: The node with the maximum genetic difference is1,with a difference of 2 XOR 1=3.-[2,5]: The node with the maximum genetic difference is2,with a difference of 5 XOR 2=7.

Input: parents =[3,7,-1,2,0,7,0,2], queries =[[4,6],[1,15],[0,5]]Output: [6,14,7]Explanation: The queries are processed as follows:-[4,6]: The node with the maximum genetic difference is0,with a difference of 6 XOR 0=6.-[1,15]: The node with the maximum genetic difference is1,with a difference of 15 XOR 1=14.-[0,5]: The node with the maximum genetic difference is2,with a difference of 5 XOR 2=7.
To answer each query efficiently, we need to find the maximum XOR of a given value with any node on the path from a given node to the root. Since the path is dynamic as we traverse the tree, we can use a Trie to store the current path’s node values and use DFS to traverse the tree. For each query at a node, we insert the node’s value into the Trie, answer the queries, and then remove the value as we backtrack.
classSolution {
classTrieNode {
val child = arrayOfNulls<TrieNode>(2)
var cnt = 0 }
funmaxGeneticDifference(parents: IntArray, queries: Array<IntArray>): IntArray {
val n = parents.size
val tree = Array(n) { mutableListOf<Int>() }
var root = -1for (i in0 until n) {
if (parents[i] == -1) root = i else tree[parents[i]].add(i)
}
val qs = Array(n) { mutableListOf<Pair<Int,Int>>() }
for (i in queries.indices) {
val(node, valq) = queries[i]
qs[node].add(valq to i)
}
val ans = IntArray(queries.size)
val trie = TrieNode()
funinsert(x: Int) {
var node = trie
for (i in17 downTo 0) {
val b = (x shr i) and 1if (node.child[b] ==null) node.child[b] = TrieNode()
node = node.child[b]!! node.cnt++ }
}
funremove(x: Int) {
var node = trie
for (i in17 downTo 0) {
val b = (x shr i) and 1 node = node.child[b]!! node.cnt-- }
}
funquery(x: Int): Int {
var node = trie
var res = 0for (i in17 downTo 0) {
val b = (x shr i) and 1if (node.child[1-b] !=null&& node.child[1-b]!!.cnt > 0) {
res = res or (1 shl i)
node = node.child[1-b]!! } else {
node = node.child[b]!! }
}
return res
}
fundfs(u: Int) {
insert(u)
for ((valq, idx) in qs[u]) ans[idx] = query(valq)
for (v in tree[u]) dfs(v)
remove(u)
}
dfs(root)
return ans
}
}
classSolution:
classTrieNode:
def__init__(self):
self.child = [None, None]
self.cnt =0defmaxGeneticDifference(self, parents: list[int], queries: list[list[int]]) -> list[int]:
n = len(parents)
tree = [[] for _ in range(n)]
root =-1for i, p in enumerate(parents):
if p ==-1:
root = i
else:
tree[p].append(i)
qs = [[] for _ in range(n)]
for idx, (node, val) in enumerate(queries):
qs[node].append((val, idx))
ans = [0] * len(queries)
trie = self.TrieNode()
definsert(x: int):
node = trie
for i in range(17, -1, -1):
b = (x >> i) &1ifnot node.child[b]:
node.child[b] = self.TrieNode()
node = node.child[b]
node.cnt +=1defremove(x: int):
node = trie
for i in range(17, -1, -1):
b = (x >> i) &1 node = node.child[b]
node.cnt -=1defquery(x: int) -> int:
node = trie
res =0for i in range(17, -1, -1):
b = (x >> i) &1if node.child[1-b] and node.child[1-b].cnt >0:
res |=1<< i
node = node.child[1-b]
else:
node = node.child[b]
return res
defdfs(u: int):
insert(u)
for val, idx in qs[u]:
ans[idx] = query(val)
for v in tree[u]:
dfs(v)
remove(u)
dfs(root)
return ans
⏰ Time complexity: O((n + q) * log M), where n is the number of nodes, q is the number of queries, and M is the maximum value (up to 2e5). Each insert, remove, and query operation on the Trie takes O(log M) time.
🧺 Space complexity: O(n * log M), for the Trie and auxiliary structures.