HDU 4757 可持久化字典树(Trie)
来源:互联网 发布:matlab数组 编辑:程序博客网 时间:2024/06/05 03:23
【题目大意】
一颗无根树,每个节点有权值,每次提问x,y,z,回答节点x到y的唯一路径上xor z的最大值。
【分析】
Trie保存每个2进制位,然后类似贪心的遍历一次即可,遍历的时候,用x,y,lca,falca的各个版本来维护是否有串即可。
【代码】
/*********************** ID:Ciocio LANG:C++ DATE:2014-1-23 TASK:Tree***********************/#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>#include <queue>using namespace std;#define MAXN 100005#define MAXQ 100005struct Tree{ Tree* lc; int sz; Tree* rc;};Tree Pool[50*MAXN];Tree* New;Tree* P[MAXN];int N,Q,logn;int Last[MAXN],Next[MAXN<<1],Y[MAXN<<1];int val[MAXN],Dep[MAXN],Fa[MAXN*2][20];void _read(int &x){ char tt=getchar(); while(tt<'0'||'9'<tt) tt=getchar(); for(x=0;'0'<=tt&&tt<='9';x=(x<<1)+(x<<3)+tt-'0',tt=getchar());}int totM;void _addedge(int u,int v){ Y[++totM]=v;Next[totM]=Last[u]; Last[u]=totM;}void _init(){ for(int i=1;i<=N;i++) _read(val[i]); int u,v; for(int i=1;i<N;i++){ _read(u);_read(v); _addedge(u,v); _addedge(v,u); }}Tree* null;Tree* Get(Tree* lc,int sz,Tree* rc){ New->lc=lc; New->sz=sz; New->rc=rc; return New++;}Tree* Insert(Tree* T,int num,int i){ if(i==-1) return Get(null,T->sz+1,null); if((num>>i)&1) return Get(Insert(T->lc,num,i-1),T->sz+1,T->rc); else return Get(T->lc,T->sz+1,Insert(T->rc,num,i-1));}void _Dfs(int u,int fa){ Fa[u][0]=fa; P[u]=Insert(P[fa],val[u],15); for(int j=Last[u];j;j=Next[j]){ int v=Y[j]; if(v!=fa) _Dfs(v,u); }}void _pre_lca(int x){ Dep[x]=Dep[Fa[x][0]]+1; for(int i=1;i<=15;i++) Fa[x][i]=Fa[Fa[x][i-1]][i-1]; for(int j=Last[x];j;j=Next[j]) if(Y[j]!=Fa[x][0]) _pre_lca(Y[j]);}int _Lca(int x,int y){ if(Dep[x]<Dep[y]) swap(x,y); int k=Dep[x]-Dep[y]; for(int i=0;i<=logn;i++) if((k>>i)&1) x=Fa[x][i]; if(x==y) return x; k=ceil(log2(Dep[x])); for(int i=k;i>=0;i--) if(Fa[x][i]!=Fa[y][i]){ x=Fa[x][i]; y=Fa[y][i]; } return Fa[x][0];}int Search(Tree* x,Tree* y,Tree* flca,Tree* lca,int key,int i){ if(i==-1) return 0; int lc_sz=x->lc->sz+y->lc->sz-flca->lc->sz-lca->lc->sz; int rc_sz=x->rc->sz+y->rc->sz-flca->rc->sz-lca->rc->sz; int tmp=((key>>i)&1); if(tmp==0){ if(lc_sz!=0) return (1<<i)+Search(x->lc,y->lc,flca->lc,lca->lc,key,i-1); return Search(x->rc,y->rc,flca->rc,lca->rc,key,i-1); } else{ if(rc_sz!=0) return (1<<i)+Search(x->rc,y->rc,flca->rc,lca->rc,key,i-1); return Search(x->lc,y->lc,flca->lc,lca->lc,key,i-1); }}void _solve(){ _Dfs(1,0); _pre_lca(1); int x,y,z,lca; while(Q--){ _read(x);_read(y);_read(z); lca=_Lca(x,y); printf("%d\n",Search(P[x],P[y],P[Fa[lca][0]],P[lca],z,15)); }}int main(){ while(scanf("%d%d",&N,&Q)!=EOF){ logn=ceil(log2(N)); memset(Last,0,sizeof Last); memset(Pool,0,sizeof Pool); memset(P,0,sizeof P); totM=0; New=Pool; null=Get(0,0,0); null->lc=null; null->rc=null; P[0]=null; _init(); _solve(); } return 0;}
0 0
- HDU 4757 可持久化字典树(Trie)
- HDU 4757 可持久化trie树
- hdu 4757 Tree(可持久化Trie)
- HDU-5801 可持久化Trie树
- hdu 4757 Tree(可持久化字典树)
- hdu-4757-Tree-树链剖分+可持久化字典树
- Hdu-4757 Tree(可持久化字典树)
- hdu 4757 Tree(可持久化字典树)
- HDU 4757 树链剖分+可持久化字典树
- HDU 4757 Tree 可持久化trie+lca
- hdu 6191 可持久化trie||线段树套trie||trie启发式合并
- HDU 4757 Tree (倍增算法求LCA + 可持久化Trie树)
- 可持久化trie
- HDU 6191 DFS序+可持久化字典树
- 可持久化字典树
- [BZOJ3261]-可持久化trie
- BZOJ 3261 可持久化字典树
- BZOJ3166 && BZOJ3261 可持久化字典树
- 简单的登录程序
- css入门之html选择器,ID选择器,类选择器,属性选择器
- EAX、ECX、EDX、EBX寄存器的作用
- Ogre引擎源码——Timer
- RMAN-06169: 无法读取数据文件的文件标头7错误原因
- HDU 4757 可持久化字典树(Trie)
- 请让我们回到爱开始的地方
- 混淆的艺术-(苍井空变凤姐)Proguard源码分析(二)Proguard参数解析
- Chapter00 上课前的准备工作
- Effective JavaScript 读书笔记 2 浮点数
- java 变成建议
- maven学习笔记(4)--web项目
- C++传递对象函数指针作为参数
- 八 手游开发神器 cocos2d-x editor 之动画和帧动画