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?
链接🔗
题解
可持久化trie? 有点感觉01Tri有点像线段树
主要技巧在用dfs序维护trie,然后子树范围等于 至
代码
#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;
}