hdu4757(LCA+可持久化字典树)
来源:互联网 发布:外资企业数据 编辑:程序博客网 时间:2024/05/16 15:16
题目链接:点这里!!!
题意:给你一个n个节点的树(n<=1e5),每个节点都有一个权值a[i](a[i]<=2^16),再给你q(q<=1e5)个询问,问你(x,y)这条路径上的权值与v异或的最大值为多少?
题解:
也是可持久化字典树,只是现在是在树上搞一搞。其实也是一样的,我们把儿子和父亲在可持久化字典树连起来就可以了,求出他们的LCA,然后乱搞就可以了!!!(具体看代码)
代码:
#include<cstdio>#include<cstring>#include<iostream>#include<sstream>#include<algorithm>#include<vector>#include<bitset>#include<set>#include<queue>#include<stack>#include<map>#include<cstdlib>#include<cmath>#define pb push_back#define pa pair<int,int>#define clr(a,b) memset(a,b,sizeof(a))#define lson lr<<1,l,mid#define rson lr<<1|1,mid+1,r#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)#define key_value ch[ch[root][1]][0]#pragma comment(linker, "/STACK:102400000000,102400000000")typedef long long LL;const LL MOD = 1000000007;const int N = 1e5+15;const int maxn = 1e6+15;const int letter = 130;const int INF = 1e9;const double pi=acos(-1.0);const double eps=1e-10;using namespace std;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int n,q,head[N],tot,a[N];int fa[N][18],deep[N],bin[18];int ch[N*18][2],sum[N*18],root[N],cnt;struct edges{ int to,next;}e[N<<1];void addedges(int u,int v){ e[tot].to=v,e[tot].next=head[u],head[u]=tot++;}int trie_insert(int x,int val){ int tmp,y; tmp=y=++cnt; for(int i=16;i>=0;i--){ ch[y][0]=ch[x][0],ch[y][1]=ch[x][1]; sum[y]=sum[x]+1; int t=val&bin[i]; t>>=i; x=ch[x][t]; ch[y][t]=++cnt; y=ch[y][t]; } sum[y]=sum[x]+1; return tmp;}int trie_query(int x,int y,int z,int val){ int ans=0,ps=a[z]; x=root[x],y=root[y],z=root[z]; for(int i=16;i>=0;i--){ int p=(val>>i)&1; if(sum[ch[x][p^1]]+sum[ch[y][p^1]]-2*sum[ch[z][p^1]]>0){ x=ch[x][p^1],y=ch[y][p^1],z=ch[z][p^1]; ans|=(1<<i); } else x=ch[x][p],y=ch[y][p],z=ch[z][p]; } return max(ans,val^ps);}void dfs(int x,int g){ root[x]=trie_insert(root[g],a[x]); for(int i=head[x];i!=-1;i=e[i].next){ int to=e[i].to; if(to==g) continue; fa[to][0]=x; deep[to]=deep[x]+1; dfs(to,x); }}int lca(int x,int y){ if(deep[x]<deep[y]) swap(x,y); int t=deep[x]-deep[y]; for(int i=16;i>=0;i--) if(t&bin[i])x=fa[x][i]; for(int i=16;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; if(x==y) return x; return fa[x][0];}void init(){ tot=cnt=0; clr(head,-1); deep[1]=0; clr(sum,0),clr(ch,0),clr(root,0),clr(fa,0);}int main(){ int x,y,z,v; bin[0]=1; for(int i=1;i<=16;i++) bin[i]=bin[i-1]<<1; while(~scanf("%d%d",&n,&q)){ init(); for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<n;i++){ scanf("%d%d",&x,&y); addedges(x,y),addedges(y,x); } fa[1][0]=0; dfs(1,0); for(int j=1;j<=16;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; while(q--){ scanf("%d%d%d",&x,&y,&v); z=lca(x,y); printf("%d\n",trie_query(x,y,z,v)); } } return 0;}
0 0
- hdu4757(LCA+可持久化字典树)
- [HDU4757][可持久化Trie][LCA]Tree[好题]
- 可持久化字典树
- BZOJ 3261 可持久化字典树
- BZOJ3166 && BZOJ3261 可持久化字典树
- 模板 可持久化字典树
- bzoj4546 -- 可持久化字典树
- hdu6191 可持久化字典树
- BZOJ 2588 [可持久化线段树][lca]
- HDU 4757 可持久化字典树(Trie)
- hdu 4757 Tree(可持久化字典树)
- [可持久化字典树 set] BZOJ 3166 [Heoi2013]Alo
- [可持久化字典树] BZOJ 4546 codechef XRQRS
- bzoj 3166 [Heoi2013]Alo 可持久化字典树
- hdu-4757-Tree-树链剖分+可持久化字典树
- bzoj3261 最大异或和(可持久化字典树)
- Codechef Xor Queries(可持久化字典树)
- Hdu-4757 Tree(可持久化字典树)
- 2014 Nordic Collegiate Programming Contest A - Amanda Lounges
- jquery ajax
- 模拟ORM框架—数据层的增加
- Intelij Idea设置系统默认换行符解决多系统协作开发换行符冲突
- Virtualbox .vdi虚拟磁盘文件瘦身方法
- hdu4757(LCA+可持久化字典树)
- Python中使用ElementTree解析XML文件
- Android Window 二 可移动悬浮窗口 WindowManager
- Caused by: java.lang.RuntimeException: A TaskDescription's primary color should be opaque的解决方案
- 【Hibernate】--关联关系映射:多对多映射
- ACCP7.0使用JAVA理解程序逻辑第十一章
- icmp应答包如何定位ping进程
- 【BZOJ】1213 [HNOI2004]高精度开根
- 高精度加法模板