leetcode1938 查询最大基因差
给定一棵n个节点的有根树,节点i的父节点为parents[i],根节点的父节点为-1,节点的基因值等于自身编号。有m个询问,queries[i]=[node[i],val[i]],返回从根节点到node[i]的路径上所有节点基因值与val[i]的异或最大值。
2<=n<=1E5; 1<=m<=3E4; 0<=val[i]<=2E5
分析:01-trie+离线+dfs。
(1)用01-trie维护有效元素集合,方便快速查询最大异或。
(2)dfs每进入一个节点时,将其加入trie,退出时移除,这样trie中始终为根节点到当前节点的路径上全部节点。
(3)通过离线处理,把询问挂到对应的节点上,遍历到对应的节点时顺带处理。
// 01-trie模板。。。
struct Query {
int idx, y;
};
class Solution {
public:
vector<int> maxGeneticDifference(vector<int>& parents, vector<vector<int>>& queries) {
int n = parents.size();
int root = -1;
std::vector<std::vector<int>> adj(n);
for (int i = 0; i < n; i++) {
if (parents[i] == -1) {
root = i;
} else {
adj[i].push_back(parents[i]);
adj[parents[i]].push_back(i);
}
}
std::vector<std::vector<Query>> vn(n);
int m = queries.size();
for (int i = 0; i < m; i++) {
vn[queries[i][0]].emplace_back(i, queries[i][1]);
}
Trie tr;
tr.init(2E5);
std::vector<int> ans(m);
auto dfs = [&](auto &&dfs, int x, int p) -> void {
tr.insert(x);
for (auto &node : vn[x]) {
ans[node.idx] = node.y ^ tr.find(node.y);
}
for (auto i : adj[x]) if (i != p) {
dfs(dfs, i, x);
}
tr.remove(x);
};
dfs(dfs, root, -1);
return ans;
}
};
浙公网安备 33010602011771号