Hdu 6191 -- Query on A Tree (persistent dictionary Tree), hdu6191 -- query
Question Link
Problem DescriptionMonkey 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 practice 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?
InputThere 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, metrics, Vn, indicating the value of node I.
The second line contains n-1 non-negative integers F1, F2, using 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 shoshould 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
OutputFor each query, just print an integer in a line indicating the largest result.
Sample Input2 21 211 32 1
Sample Output23 question: there is a tree composed of n nodes, each of which has a weight value. Now q queries, each input u, x indicates that the weight on a node is different in the subtree where u is the root node or the maximum value obtained by x? Idea: The persistence trie tree is similar to the Chairman tree. It has n versions of the dictionary tree. When traversing the tree, it creates a new dictionary tree, but in fact, compared with the old one, only the log2 (1e9) node is added each time. In addition, the maximum variance or value is obtained on the subtree u, therefore, you need to save the node number before the u subtree and the number of the last node in the u subtree, and make a difference to get the corresponding data. The Code is as follows:
#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\n",query(root[la[u]-1],root[to[u]],0,x,30)); } } return 0;}