码迷,mamicode.com
首页 > 其他好文 > 详细

[hdu 6191] Query on A Tree

时间:2017-09-10 21:44:06      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:ack   mit   play   set   who   网上   otto   sample   problem   

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,?Fn1Fi 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.

2n,q105

0Vi109

1Fin, the root of the tree is node 1.

1un,0x109
 
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 }
View Code

 

[hdu 6191] Query on A Tree

标签:ack   mit   play   set   who   网上   otto   sample   problem   

原文地址:http://www.cnblogs.com/whc200305/p/7502145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!