chenfy27的刷题记录

导航

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;
    }
};

posted on 2024-12-29 16:40  chenfy27  阅读(9)  评论(0)    收藏  举报