zoukankan      html  css  js  c++  java
  • hdu 6191--Query on A Tree(持久化字典树)

    题目链接

    Problem Description
    Monkey A lives on a tree, he always plays on this tree.

    One day, monkey A learned about one of the bit-operations, xor. He was keen of this interesting operation and wanted to practise it at once.

    Monkey A gave a value to each node on the tree. And he was curious about a problem.

    The problem is how large the xor result of number x and one node value of label y can be, when giving you a non-negative integer x and a node label u indicates that node y is in the subtree whose root is u(y can be equal to u).

    Can you help him?
     
    Input
    There are no more than 6 test cases.

    For each test case there are two positive integers n and q, indicate that the tree has n nodes and you need to answer q queries.

    Then two lines follow.

    The first line contains n non-negative integers V1,V2,,Vn, indicating the value of node i.

    The second line contains n-1 non-negative integers F1,F2,Fn1Fi means the father of node i+1.

    And then q lines follow.

    In the i-th line, there are two integers u and x, indicating that the node you pick should be in the subtree of u, and x has been described in the problem.

    2n,q105

    0Vi109

    1Fin, the root of the tree is node 1.

    1un,0x109
     
    Output
    For each query, just print an integer in a line indicating the largest result.
     
    Sample Input
    2 2
    1 2
    1
    1 3
    2 1
     
    Sample Output
    2
    3
     
     
    题意:有一棵由n个节点构成的树,每个点上有一个权值,现在q次询问,每次输入u,x 表示以u为根节点的子树上 以某个节点上的权值异或x得到的最大值?
     
    思路:持久化 trie 树,感觉和主席树差不多,是有 n 个版本的字典树,在遍历树的过程中经过点时,建立新的字典树,但实际上与旧的相比每次只是增加了log2(1e9)个节点,另外是在子树 u 上求最大异或值,所以需要保存 u 子树之前节点号和 u 子树中的最后一个节点的编号,作差即可得到相应的数据;
     
    代码如下:
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int N=1e5+5;
    int a[N];
    struct Node
    {
        int son[2];
        int sum[2];
    }node[35*N];
    vector<int>G[N];
    int la[N],to[N],root[N];
    int tot1,tot2;
    
    void init()
    {
       node[0].son[0]=node[0].son[1]=0;
       node[0].sum[0]=node[0].sum[1]=0;
       root[0]=0;
       tot1=tot2=0;
       for(int i=1;i<N;i++) G[i].clear();
    }
    void build(int pre,int now,int x,int deep)
    {
        if(deep<0) return ;
        int tmp=!!(x&(1<<deep));
        node[now]=node[pre];
        node[now].sum[tmp]++;
        build(node[pre].son[tmp],node[now].son[tmp]=++tot2,x,deep-1);
    }
    void dfs(int now)
    {
        la[now]=++tot1;
        build(root[la[now]-1],root[la[now]]=++tot2,a[now],30);
        for(int i=0;i<G[now].size();i++)
        {
            int v=G[now][i];
            dfs(v);
        }
        to[now]=tot1;
    }
    int query(int pre,int now,int sum,int x,int deep)
    {
        if(deep<0) return sum;
        int tmp=!!(x&(1<<deep));
        if(node[now].sum[tmp^1]>node[pre].sum[tmp^1])
            return query(node[pre].son[tmp^1],node[now].son[tmp^1],sum|(1<<deep),x,deep-1);
        return query(node[pre].son[tmp],node[now].son[tmp],sum,x,deep-1);
    }
    int main()
    {
        int n,q;
        while(scanf("%d%d",&n,&q)!=EOF)
        {
            init();
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            for(int i=2;i<=n;i++)
            {
                int x; scanf("%d",&x);
                G[x].push_back(i);
            }
            dfs(1);
            while(q--)
            {
                int u,x; scanf("%d%d",&u,&x);
                printf("%d
    ",query(root[la[u]-1],root[to[u]],0,x,30));
            }
        }
        return 0;
    }
  • 相关阅读:
    HDU 3951 (博弈) Coin Game
    HDU 3863 (博弈) No Gambling
    HDU 3544 (不平等博弈) Alice's Game
    POJ 3225 (线段树 区间更新) Help with Intervals
    POJ 2528 (线段树 离散化) Mayor's posters
    POJ 3468 (线段树 区间增减) A Simple Problem with Integers
    HDU 1698 (线段树 区间更新) Just a Hook
    POJ (线段树) Who Gets the Most Candies?
    POJ 2828 (线段树 单点更新) Buy Tickets
    HDU 2795 (线段树 单点更新) Billboard
  • 原文地址:https://www.cnblogs.com/chen9510/p/7677618.html
Copyright © 2011-2022 走看看