|
| 1 | +from collections import defaultdict |
| 2 | + |
| 3 | +class TrieNode: |
| 4 | + def __init__(self): |
| 5 | + self.children = {} |
| 6 | + self.count = 0 |
| 7 | + |
| 8 | +class Trie: |
| 9 | + def __init__(self): |
| 10 | + self.root = TrieNode() |
| 11 | + |
| 12 | + def insert(self, num): |
| 13 | + node = self.root |
| 14 | + for i in range(17, -1, -1): |
| 15 | + bit = (num >> i) & 1 |
| 16 | + if bit not in node.children: |
| 17 | + node.children[bit] = TrieNode() |
| 18 | + node = node.children[bit] |
| 19 | + node.count += 1 |
| 20 | + |
| 21 | + def remove(self, num): |
| 22 | + node = self.root |
| 23 | + for i in range(17, -1, -1): |
| 24 | + bit = (num >> i) & 1 |
| 25 | + if bit in node.children: |
| 26 | + node = node.children[bit] |
| 27 | + node.count -= 1 |
| 28 | + |
| 29 | + def maxXOR(self, num): |
| 30 | + node = self.root |
| 31 | + max_xor = 0 |
| 32 | + for i in range(17, -1, -1): |
| 33 | + bit = (num >> i) & 1 |
| 34 | + toggled_bit = 1 - bit |
| 35 | + if toggled_bit in node.children and node.children[toggled_bit].count > 0: |
| 36 | + max_xor |= (1 << i) |
| 37 | + node = node.children[toggled_bit] |
| 38 | + else: |
| 39 | + node = node.children[bit] |
| 40 | + return max_xor |
| 41 | + |
| 42 | +class Solution: |
| 43 | + def maxGeneticDifference(self, parents, queries): |
| 44 | + n = len(parents) |
| 45 | + |
| 46 | + # Build the tree as an adjacency list |
| 47 | + tree = defaultdict(list) |
| 48 | + root = -1 |
| 49 | + for i in range(n): |
| 50 | + if parents[i] == -1: |
| 51 | + root = i |
| 52 | + else: |
| 53 | + tree[parents[i]].append(i) |
| 54 | + |
| 55 | + # Group queries by the node |
| 56 | + query_map = defaultdict(list) |
| 57 | + for idx, (node, val) in enumerate(queries): |
| 58 | + query_map[node].append((val, idx)) |
| 59 | + |
| 60 | + # Result array |
| 61 | + res = [0] * len(queries) |
| 62 | + |
| 63 | + # Trie to store and query the path genetic values |
| 64 | + trie = Trie() |
| 65 | + |
| 66 | + # Depth-first search to solve the queries |
| 67 | + def dfs(node): |
| 68 | + trie.insert(node) |
| 69 | + if node in query_map: |
| 70 | + for val, idx in query_map[node]: |
| 71 | + res[idx] = trie.maxXOR(val) |
| 72 | + for child in tree[node]: |
| 73 | + dfs(child) |
| 74 | + trie.remove(node) |
| 75 | + |
| 76 | + # Start DFS from the root |
| 77 | + dfs(root) |
| 78 | + |
| 79 | + return res |
0 commit comments