Query on A Tree
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 733 Accepted Submission(s): 275
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
Source
显然,又是data structure。。。
网上有用DFS序来做的,但是本蒟蒻并不太清楚他们dalao的做法,所以只是大了一发可持久化trie合并。。
对于这一题,主要涉及trie的合并,要将u的子节点的信息合并到u的身上去。
那么,假设要将v的信息并到u上,则:
1 int merge(int u,int v) { 2 if (!u) return v; 3 if (!v) return u; 4 ch[u][0]=merge(ch[u][0],ch[v][0]); 5 ch[u][1]=merge(ch[u][1],ch[v][1]); 6 return u; 7 }
那么这题差不多就可以A了。
code:
1 %:pragma gcc optimize(3) 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #define jug(i,x) (((1<<i)&x)>0) 7 #define M(a,x) memset(a,x,sizeof a) 8 using namespace std; 9 const int N=100005,Nod=12000005; 10 int n,tot,Q,a[N],lnk[N],nxt[N],son[N]; 11 int ro[N],ans[N]; 12 struct que {int v,i;}; 13 vector <que> qr[N]; 14 struct persistent_trie { 15 int cnt,ch[Nod][2]; 16 void init() {cnt=1;} 17 int newnode() { 18 M(ch[cnt],0); 19 return cnt++; 20 } 21 int merge(int x,int y) { 22 if (!x) return y; 23 if (!y) return x; 24 ch[x][0]=merge(ch[x][0],ch[y][0]); 25 ch[x][1]=merge(ch[x][1],ch[y][1]); 26 return x; 27 } 28 void insert(int x,int v) { 29 int u=ro[x]; 30 for (int i=30; i>=0; i--) { 31 bool c=jug(i,v); 32 if (!ch[u][c]) ch[u][c]=newnode(); 33 u=ch[u][c]; 34 } 35 } 36 int query(int x,int v) { 37 int u=ro[x],ret=0; 38 for (int i=30; i>=0; i--) { 39 bool c=jug(i,v); 40 if (ch[u][1-c]) ret|=(1<<i),u=ch[u][1-c]; 41 else u=ch[u][c]; 42 } 43 return ret; 44 } 45 }pt; 46 inline int read() { 47 int x=0; char ch=getchar(); 48 while (ch<‘0‘||ch>‘9‘) ch=getchar(); 49 while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); 50 return x; 51 } 52 void add(int x,int y) { 53 nxt[++tot]=lnk[x],son[tot]=y,lnk[x]=tot; 54 } 55 void DFS(int x) { 56 ro[x]=pt.newnode(); 57 pt.insert(x,a[x]); 58 for (int j=lnk[x]; j; j=nxt[j]) 59 DFS(son[j]),ro[x]=pt.merge(ro[x],ro[son[j]]); 60 for (int i=0,si=qr[x].size(); i<si; i++) 61 ans[qr[x][i].i]=pt.query(x,qr[x][i].v); 62 } 63 int main() { 64 while (scanf("%d%d",&n,&Q)!=EOF) { 65 tot=0,M(lnk,0),M(nxt,0),M(ans,0),pt.init(); 66 for (int i=1; i<=n; i++) a[i]=read(); 67 for (int i=1; i<n; i++) { 68 int x=read(); add(x,i+1); 69 } 70 for (int i=1; i<=n; i++) qr[i].clear(); 71 for (int i=1; i<=Q; i++) { 72 int x=read(); que now; 73 now.i=i,now.v=read(),qr[x].push_back(now); 74 } 75 DFS(1); 76 for (int i=1; i<=Q; i++) printf("%d\n",ans[i]); 77 } 78 return 0; 79 }