• 2017广西邀请赛 Query on A Tree (可持续化字典树)


     Query on A Tree

    时间限制: 8 Sec  内存限制: 512 MB
    提交: 15  解决: 3
    [提交][状态][讨论版]

    题目描述

    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?

    输入

    There are no more than six test cases.
    For each test case there are two positive integers n(2 ≤ n ≤ 105) and q(2 ≤ q ≤ 105), indicating 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(0 ≤ Vi ≤ 109), indicating the value of node i. The root of the tree is node 1.
    The second line contains n-1 non-negative integers F1, F2,...Fn−1, Fi(1 ≤ Fi ≤ n) means the father of node i + 1.
    And then q lines follow.
    In the i-th line, there are two integers u(1 ≤ u ≤ n) and x(0 ≤ x ≤ 109), indicating that the node you pick should be in the subtree of u, and x has been described in the problem.

    输出

     

    样例输入

    2 2
    1 2
    1
    1 3
    2 1
    

    样例输出

    2
    3
    【题意】给你一棵树,每个节点有权值,Q次询问,求u为跟的子树里与x亦或后的值最大是多少。
    【分析】可持续化字典树可用来解决一段区间内与x亦或后的值最大是多少,这里可以用dfs序将子树转为序列。
    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define met(a,b) memset(a,b,sizeof a)
    #define pb push_back
    #define mp make_pair
    #define rep(i,l,r) for(int i=(l);i<=(r);++i)
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int N = 2e5+5;;
    const int M = 17;
    const int mod = 1e9+7;
    const int mo=123;
    const double pi= acos(-1.0);
    typedef pair<int,int>pii;
     
    int bin[31];
    int n,m,tot;
    int a[N],root[N],id[N],st[N],ed[N];
    vector<int>edg[N];
    struct trie{
        int cnt;
        int ch[N*32][2],sum[N*32];
        void init(){
            met(ch,0);met(sum,0);
            cnt=0;
        }
        int insert(int x,int val){
            int tmp,y;tmp=y=++cnt;
            for(int i=30;i>=0;i--)
            {
                ch[y][0]=ch[x][0];ch[y][1]=ch[x][1];
                sum[y]=sum[x]+1;
                int t=val&bin[i];t>>=i;
                x=ch[x][t];
                ch[y][t]=++cnt;
                y=ch[y][t];
            }
            sum[y]=sum[x]+1;
            return tmp;
        }
        int query(int l,int r,int val){
            int tmp=0;
            for(int i=30;i>=0;i--)
            {
                int t=val&bin[i];t>>=i;
                if(sum[ch[r][t^1]]-sum[ch[l][t^1]])
                    tmp+=bin[i],r=ch[r][t^1],l=ch[l][t^1];
                else r=ch[r][t],l=ch[l][t];
            }
            return tmp;
        }
    }trie;
    void dfs(int u,int fa){
        st[u]=++tot;
        id[tot]=u;
        for(int i=0;i<edg[u].size();i++){
            int v=edg[u][i];
            if(v==fa)continue;
            dfs(v,u);
        }
        ed[u]=tot;
    }
    int main(){
        bin[0]=1;for(int i=1;i<=30;i++)bin[i]=bin[i-1]<<1;
        while(~scanf("%d%d",&n,&m)){
            root[0]=0;tot=0;
            trie.init();
            for(int i=1;i<=n;i++)scanf("%d",&a[i]),edg[i].clear();
            for(int i=2;i<=n;i++){
                int v;
                scanf("%d",&v);
                edg[v].pb(i);
            }
            dfs(1,0);
            for(int i=1;i<=n;i++)root[i]=trie.insert(root[i-1],a[id[i]]);
            int l,r,x,u;
            while(m--){
                scanf("%d%d",&u,&x);
                l=st[u];r=ed[u];
                printf("%d
    ",trie.query(root[l-1],root[r],x));
            }
        }
        return 0;
    }
  • 相关阅读:
    后缀表达式
    Linux中的硬链接和软链接
    C++中const总结
    atexit()函数
    Linux中的0号进程和1号进程
    什么是可重入函数和不可重入函数
    在线(Online)算法
    PHP验证IP地址输入的准确性:数组数值验证
    PHP网页计时工具——SESSION问题
    软件版本号命名规则
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/7457308.html
Copyright © 2020-2023  润新知