[hdu 4757] Tree

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[hdu 4757] Tree相关的知识,希望对你有一定的参考价值。

Tree

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 2117    Accepted Submission(s): 634


Problem Description
  Zero and One are good friends who always have fun with each other. This time, they decide to do something on a tree which is a kind of graph that there is only one path from node to node. First, Zero will give One an tree and every node in this tree has a value. Then, Zero will ask One a series of queries. Each query contains three parameters: x, y, z which mean that he want to know the maximum value produced by z xor each value on the path from node x to node y (include node x, node y). Unfortunately, One has no idea in this question. So he need you to solve it.
 

 

Input
  There are several test cases and the cases end with EOF. For each case:

  The first line contains two integers n(1<=n<=10^5) and m(1<=m<=10^5), which are the amount of tree’s nodes and queries, respectively.

  The second line contains n integers a[1..n] and a[i](0<=a[i]<2^{16}) is the value on the ith node.

  The next n–1 lines contains two integers u v, which means there is an connection between u and v.

  The next m lines contains three integers x y z, which are the parameters of Zero’s query.
 

 

Output
  For each query, output the answer.
 

 

Sample Input

3 2
1 2 2
1 2
2 3
1 3 1
2 3 2

 

Sample Output
3
0
 

 

Source
 
 

题目意思就是给你一棵树,每个点都有一个点权,然后给你m个询问,每个询问有三个数x,y,z,表示求出从x到y的简单路径上面的点中,点权^z最大的是多少。

显然要用到trie,但是看起来很难的样子。。。我们不知道到底x,y是多少,而且我们也不可能对于每一对x,y路径上的点都建立一棵字典树,那怎么办办???

要用到可持久化数据结构。Persistant Trie!!!

就像主席树那样(然而我并不会),对于每一个节点要记录一个根节点ro[i],这个ro不再一定是1了,因为它需要做到可持久化,所以它可以是其他。

由于可持久化trie似乎有很多写法,所以就不讲写法了(我也不会讲,不是特别熟悉)。

对于这题,主要要注意的是,在insert的时候,要将节点x的父节点的信息下传(也就是说sz[x]表示大小前缀和)。

由于sz[x]+sz[y]-2*sz[lca(x,y)]>=0,我们就以这个条件来在query的时候继续向下访问。

技术分享
 1 %:pragma gcc optimize(2)
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define M(a,x) memset(a,x,sizeof a)
 6 #define jug(i,x) (((1<<i)&x)>0)
 7 using namespace std;
 8 const int N=100005,ML=17,MN=1700005;
 9 int n,Q,tot,ans;
10 int a[N],lnk[N],nxt[N*2],son[N*2];
11 int dep[N],fa[N][ML];
12 int LCA(int x,int y){
13     if (dep[x]<dep[y]) swap(x,y);
14     int dif=dep[x]-dep[y];
15     for (int i=ML-1; i>=0; i--) if (jug(i,dif)) x=fa[x][i];
16     if (x==y) return x;
17     for (int i=ML-1; i>=0; i--)
18         if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
19     return fa[x][0];
20 }
21 struct Persistent_Trie{
22     int ch[MN][2],sz[MN],ro[N];
23     void init() {M(sz,0),M(ro,0);}
24     int newnode() {
25         M(ch[tot],0),sz[tot]=0;
26         return tot++;
27     }
28     void insert(int x,int y,int v) {
29         x=ro[x],y=ro[y];
30         for (int i=15; i>=0; i--) {
31             bool c=jug(i,v);
32             if (!ch[x][c]) {
33                 int idx=newnode();
34                 ch[x][c]=idx,ch[x][!c]=ch[y][!c];
35                 sz[ch[x][c]]=sz[ch[y][c]];
36             }
37             x=ch[x][c],y=ch[y][c],sz[x]++;
38         }
39     }
40     int query(int x,int y,int v) {
41         int z=LCA(x,y),ret=a[z]^v,re=0;
42         x=ro[x],y=ro[y],z=ro[z];
43         for (int i=15; i>=0; i--) {
44             bool c=jug(i,v);
45             if (sz[ch[x][!c]]+sz[ch[y][!c]]-2*sz[ch[z][!c]]>0)
46                 re+=1<<i,c=!c;
47             x=ch[x][c],y=ch[y][c],z=ch[z][c];
48         }
49         return max(ret,re);
50     }
51 }pt;
52 inline int read() {
53     int x=0; char ch=getchar();
54     while (ch<0||ch>9) ch=getchar();
55     while (ch>=0&&ch<=9) x=x*10+ch-0,ch=getchar();
56     return x;
57 }
58 void add(int x,int y) {
59     nxt[++tot]=lnk[x],son[tot]=y,lnk[x]=tot;
60 }
61 void DFS(int x,int y) {
62     fa[x][0]=y,dep[x]=dep[y]+1;
63     pt.ro[x]=pt.newnode();
64     pt.insert(x,y,a[x]);
65     for (int j=lnk[x]; j; j=nxt[j])
66         if (son[j]!=y) DFS(son[j],x);
67 }
68 int main() {
69     while (scanf("%d%d",&n,&Q)!=EOF) {
70         tot=0,M(lnk,0),M(nxt,0),M(fa,0),pt.init();
71         for (int i=1; i<=n; i++) a[i]=read();
72         for (int i=1; i<n; i++) {
73             int x=read(),y=read();
74             add(x,y),add(y,x);
75         }
76         dep[0]=0,tot=1,DFS(1,0);
77         for (int j=1; j<ML; j++)
78             for (int i=1; i<=n; i++) fa[i][j]=fa[fa[i][j-1]][j-1];
79         for (; Q; Q--){
80             int x=read(),y=read(),z=read();
81             printf("%d\n",pt.query(x,y,z));
82         }
83     }
84     return 0;
85 }
View Code

(讲的可能非常不清楚,希望readers能够及时纠正里面可能存在的错误和漏洞,感谢!)

以上是关于[hdu 4757] Tree的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4757 Tree(可持久化字典树)

[可持久化Trie][HDU4757] Tree

HDU 4557 Tree(可持久化字典树 + LCA)

hdu4757 可持续字典树

hdu4757 (可持久化字典树+LCA)

hdu4757 可持续化01字典树+LCA