HDU 4757 Tree 可持久化字典树 trie

http://acm.hdu.edu.cn/showproblem.php?pid=4757

给出一棵树,每个节点有权值,每次查询节点 (u,v) 以及 val,问 u 到 v 路径上的某个节点与 val 异或最大的值是多少。

和可持久化线段树差不多,看代码吧。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<vector>
 7 using namespace std;
 8 #define LL long long
 9 const int maxn=100010;
10 const int maxm=3000010;
11 int n,m;
12 int a[maxn]={},fa[maxn][20]={},dep[maxn]={},rt[maxn]={};
13 int sig[maxm][2]={},sz[maxm]={},cnt=0;
14 struct nod{int y,next;}e[maxn*2];int head[maxn],tot=0;
15 inline void init(int x,int y){e[++tot].y=y;e[tot].next=head[x];head[x]=tot;}
16 inline int getnew(){
17     sig[++cnt][0]=0;sig[cnt][1]=0;
18     sz[cnt]=0;return cnt;
19 }
20 inline void bui(int x,int pa,int val){
21     rt[x]=getnew();pa=rt[pa];
22     x=rt[x];
23     for(int i=15;i>=0;--i){
24         int ch=(val>>i)&1;
25         if(!sig[x][ch]){
26             int id=getnew();
27             sig[x][ch]=id; sig[x][!ch]=sig[pa][!ch];
28             sz[sig[x][ch]]=sz[sig[pa][ch]];
29         }
30         x=sig[x][ch];pa=sig[pa][ch];
31         ++sz[x];
32     }
33 }
34 void dfs(int x){
35     bui(x,fa[x][0],a[x]);
36     for(int i=1;fa[x][i-1];++i)fa[x][i]=fa[fa[x][i-1]][i-1];
37     for(int i=head[x];i;i=e[i].next){
38         if(e[i].y==fa[x][0])continue;
39         fa[e[i].y][0]=x;dep[e[i].y]=dep[x]+1;dfs(e[i].y);
40     }
41 }
42 inline int getlca(int x,int y){
43     if(dep[x]<dep[y])swap(x,y);
44     for(int i=19;i>=0;--i)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
45     if(x==y)return x;
46     for(int i=19;i>=0;--i)if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}
47     return fa[x][0];
48 }
49 int Query(int x,int y,int val){
50     int lc=getlca(x,y); int res=a[lc]^val;
51     x=rt[x];y=rt[y];lc=rt[lc];
52     int ret=0;
53     for(int i=15;i>=0;--i){
54         int ch=(val>>i)&1;
55         if(sz[sig[x][!ch]]+sz[sig[y][!ch]]-2*sz[sig[lc][!ch]]>0){
56             ret+=1<<i;
57             ch=!ch;
58         }
59         x=sig[x][ch];y=sig[y][ch];lc=sig[lc][ch];
60     }
61     return max(res,ret);
62 }
63 int main(){
64     while(~scanf("%d%d",&n,&m)){
65         memset(head,0,sizeof(head));memset(rt,0,sizeof(rt));
66         memset(sig,0,sizeof(sig));memset(fa,0,sizeof(fa));
67         int x,y,z;tot=0;cnt=0;
68         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
69         for(int i=1;i<n;i++){scanf("%d%d",&x,&y);init(x,y);init(y,x);}
70         dep[1]=1;dfs(1);
71         for(int i=1;i<=m;i++){
72             scanf("%d%d%d",&x,&y,&z);
73             printf("%d\n",Query(x,y,z));
74         }
75     }
76     return 0;
77 }
View Code

猜你喜欢

转载自www.cnblogs.com/137shoebills/p/9127081.html