LC1938-查询最大基因差


1938. 查询最大基因差

离线 + \(Trie\)

建树后\(dfs\),每访问一个节点 \(v\),就插入 \(Trie\) ,并回答v的所有询问,然后将 \(v\)\(Trie\)中删去。

using PII = pair;
const int N = 1e5 + 10;
int son[N * 18][2], idx, cnt[N * 18];
class Solution {
public:
    vectorans;
    vector>q;
    void insert(int x){
        int p = 0;
        for(int i = 17; i >= 0; --i){
            int u = x >> i & 1;
            if(!son[p][u]) son[p][u] = ++idx;
            p = son[p][u];
            cnt[p] ++;
        }
    }
    int query(int x){
        int res = 0, p = 0;
        for(int i = 17; i >= 0; --i){
            int u = x >> i & 1;
            if(cnt[son[p][!u]]) res += 1 << i, p = son[p][!u];
            else p = son[p][u];
        }
        return res;
    }
    void remove(int x){
        int p = 0;
        for(int i = 17; i >= 0; --i){
            int u = x >> i & 1;
            if(!son[p][u]) son[p][u] = ++idx;
            p = son[p][u];
            cnt[p] --;
        }
    }
    void dfs(vector> &G, int root){
        insert(root);
        for(int i = 0; i < q[root].size(); ++i)
            ans[q[root][i].first] = max(ans[q[root][i].first], query(q[root][i].second));
        for(auto& e : G[root]) dfs(G, e);
        remove(root);
    }
    vector maxGeneticDifference(vector& parents, vector>& queries) {
        idx = 0;
        memset(son, 0, sizeof son);
        memset(cnt, 0, sizeof cnt);
        int n = parents.size(), root = -1;
        ans.resize(queries.size());
        q.resize(N + 1);
        vector>G(n + 1);
        for(int i = 0; i < n; ++i)  // 建图
            if(parents[i] == -1) root = i;
            else G[parents[i]].push_back(i);
        for(int i = 0; i < queries.size(); ++i) q[queries[i][0]].push_back({i ,queries[i][1]});//离线存储询问
        dfs(G, root);
        return ans;
    }
};

相关