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,⋯Fn−1, Fi 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.
2≤n,q≤105
0≤Vi≤109
1≤Fi≤n, the root of the tree is node 1.
1≤u≤n,0≤x≤109
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
第一次做可持久化字典树,感觉和主席树对线段树的更改好像啊,也是现在的状态减去过去的状态然后找答案
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+5;
ll mm;
int tree[maxn*35][2],son[maxn*35][2],rt[maxn],cnt,sta[maxn],fin[maxn];
int head[maxn],tot,now;
ll a[maxn];
struct node
{
int to,next;
}e[maxn*2];
void add(int x,int y)
{
e[tot].to=y;
e[tot].next=head[x];
head[x]=tot++;
}
void build(int last,int root,ll num,ll ret)
{
if(ret==0)
return ;
ll a=ret#
int v=(a==ret)?1:0;
tree[root][v]=tree[last][v]+1;
tree[root][v^1]=tree[last][v^1];
son[root][v^1]=son[last][v^1];
build(son[last][v],son[root][v]=++cnt,num,ret/2);
}
void dfs(int fa)
{
sta[fa]=++now;
build(rt[sta[fa]-1],rt[sta[fa]]=++cnt,a[fa],mm);
for(int i=head[fa];~i;i=e[i].next)
{
int ne=e[i].to;
dfs(ne);
}
fin[fa]=now;
}
ll query(int last,int root,ll num,ll sum,ll ret)
{
if(ret==0)
return sum;
ll a=ret#
int v=(a==ret)?0:1;
if(tree[root][v]-tree[last][v]>0)
return query(son[last][v],son[root][v],num,sum+ret,ret/2);
else
return query(son[last][v^1],son[root][v^1],num,sum,ret/2);
}
int main()
{
int n,q;
mm=1;
for(int i=1;i<=31;i++)
mm*=2;
while(~scanf("%d%d",&n,&q))
{
memset(head,-1,sizeof(head));
memset(rt,0,sizeof(rt));
memset(tree,0,sizeof(tree));
cnt=tot=now=0;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
int x,y;
ll val;
for(int i=2;i<=n;i++)
{
scanf("%d",&x);
add(x,i);
}
dfs(1);
for(int i=1;i<=q;i++)
{
scanf("%d%lld",&x,&val);
printf("%lld\n",query(rt[sta[x]-1],rt[fin[x]],val,0,mm));
}
}
return 0;
}