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
原创粉丝点击