1. 程式人生 > >[hdu 4757] Tree

[hdu 4757] Tree

註意 region one include hdu 字典 lca 最大 san

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 2013 ACM/ICPC Asia Regional Nanjing Online

題目意思就是給你一棵樹,每個點都有一個點權,然後給你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