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 array ans
where ans[i]
is the answer to the ith
query.
Example 1:
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 is 0, with a difference of 2 XOR 0 = 2. - [3,2]: The node with the maximum genetic difference is 1, with a difference of 2 XOR 1 = 3. - [2,5]: The node with the maximum genetic difference is 2, with a difference of 5 XOR 2 = 7.
Example 2:
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 is 0, with a difference of 6 XOR 0 = 6. - [1,15]: The node with the maximum genetic difference is 1, with a difference of 15 XOR 1 = 14. - [0,5]: The node with the maximum genetic difference is 2, with a difference of 5 XOR 2 = 7.
Constraints:
2 <= parents.length <= 105
0 <= parents[i] <= parents.length - 1
for every nodei
that is not the root.parents[root] == -1
1 <= queries.length <= 3 * 104
0 <= nodei <= parents.length - 1
0 <= vali <= 2 * 105
Companies: Media.net
Related Topics:
Array, Bit Manipulation, Trie
Similar Questions:
Hints:
- How can we use a trie to store all the XOR values in the path from a node to the root?
- How can we dynamically add the XOR values with a DFS search?
// OJ: https://leetcode.com/problems/maximum-genetic-difference-query/
// Author: github.com/lzl124631x
// Time: O(P + Q)
// Space: O(P + Q)
struct TrieNode {
TrieNode *next[2] = {};
int cnt = 0;
};
class Solution {
void addNumber(TrieNode *node, int n, int d) {
for (int i = 17; i >= 0; --i) {
int b = n >> i & 1;
if (!node->next[b]) node->next[b] = new TrieNode();
node = node->next[b];
node->cnt += d;
}
}
int maxDiff(TrieNode *node, int n) {
int ans = 0;
for (int i = 17; i >= 0; --i) {
int b = n >> i & 1, r = 1 - b;
if (node->next[r] && node->next[r]->cnt) node = node->next[r], ans |= (1 << i);
else node = node->next[b];
}
return ans;
}
public:
vector<int> maxGeneticDifference(vector<int>& P, vector<vector<int>>& Q) {
int N = P.size(), rootIndex;
vector<vector<pair<int, int>>> Qs(N);
for (int i = 0; i < Q.size(); ++i) Qs[Q[i][0]].emplace_back(i, Q[i][1]);
vector<vector<int>> G(N);
for (int i = 0; i < N; ++i) {
if (P[i] == -1) rootIndex = i;
else G[P[i]].push_back(i);
}
TrieNode root;
vector<int> ans(Q.size());
function<void(int, int)> dfs = [&](int u, int prev) {
addNumber(&root, u, 1);
for (auto &[idx, val] : Qs[u]) ans[idx] = maxDiff(&root, val);
for (int v : G[u]) {
if (v == prev) continue;
dfs(v, u);
}
addNumber(&root, u, -1);
};
dfs(rootIndex, -1);
return ans;
}
};