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?

链接🔗

「HDU 6191 」Query on A Tree

题解

可持久化trie? 有点感觉01Tri有点像线段树
主要技巧在用dfs序维护trie,然后子树范围等于id[x]1id[x]-1id[x]+size[x]1id[x] + size[x]-1

代码

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxd = 1e5+10;
int t[maxd*32][2],val[maxd*32][2],sz[maxd];
int rt[maxd],tot,num;
int v[maxd],id[maxd];
vector<int> G[maxd];
void insert(int &now,int last,int x,int p)
{   
    now = ++tot;if(p<0) return;
    int c = (x >> p) & 1;
    t[now][0] = t[last][0];
    t[now][1] = t[last][1];
    val[now][c] = val[last][c]+1;
    val[now][c^1] = val[last][c^1];
    insert(t[now][c],t[last][c],x,p-1);
}
int query(int now,int last,int x)
{
    int ans = 0;
    for(int i=30;i>=0;i--)
    {
        int c = (x >> i) & 1;
        if(val[now][c^1] - val[last][c^1] > 0) ans += (1<<i),c^=1;
        now = t[now][c], last = t[last][c];
    }
    return ans;
}
void dfs(int x)
{
    id[x] = ++num;sz[x]=1;
    insert(rt[id[x]],rt[id[x]-1],v[x],30);
    for(int i= 0;i<G[x].size();i++)
    {
        int v = G[x][i];dfs(v);
        sz[x] += sz[v];
    }
}

int main()
{
    // freopen("a.in","r",stdin);
    // freopen("k.out","w",stdout);

    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        memset(t,0,sizeof(t));
        memset(rt,0,sizeof(rt));
        memset(val,0,sizeof(val));
        num  = tot = 0;

        for(int i=1;i<=n;i++) scanf("%d",&v[i]);
        //printf("%d %d\n",n,m);
        for(int i=2;i<=n;i++)
        {
           int x;scanf("%d",&x);
           G[x].push_back(i);
        }
        int root  = 1;
        dfs(root);
        // for(int i=1;i<=n;i++)
        //     printf("%d %d\n",i,rt[i]);

        for(int i=1;i<=m;i++)
        {
           int x,y;scanf("%d %d",&x,&y);
           //printf("%d %d\n",id[x]+sz[x]-1,id[x]-1);
           printf("%d\n",query(rt[id[x]+sz[x]-1],rt[id[x]-1],y));
        }
        for(int i=1;i<=n;i++) G[i].clear();
    }
    return 0;
}