题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4757

题意:给出一棵树,节点有权值。每次询问x到y的路径上与z抑或的最大值。

思路:可持久化trie。

struct Node
{
    int c[2],cnt;
};

Node a[2000005];
int cnt;

int newNode()
{
    cnt++;
    a[cnt].c[0]=a[cnt].c[1]=a[cnt].cnt=0;
    return cnt;
}

struct node
{
    int v,next;
};

node edges[N<<1];
int head[N],e;

void add(int u,int v)
{
    edges[e].v=v;
    edges[e].next=head[u];
    head[u]=e++;
}

int n,m,f[N][20],d[N],dep[N],root[N];

void insert(int u,int p,int d)
{
    int x=root[u],y=root[p],i,k;
    for(i=15;i>=0;i--)
    {
        k=(d>>i)&1;
        a[x].c[k]=newNode();
        a[x].c[!k]=a[y].c[!k];
        a[a[x].c[k]].cnt=a[a[y].c[k]].cnt+1;
        x=a[x].c[k];
        y=a[y].c[k];
    }
}

void DFS(int u,int pre)
{
    f[u][0]=pre; dep[u]=dep[pre]+1;
    root[u]=newNode();
    insert(u,pre,d[u]);
    int i,v;
    for(i=head[u];i!=-1;i=edges[i].next)
    {
        v=edges[i].v;
        if(v==pre) continue;
        DFS(v,u);
    }
}

int getLca(int x,int y)
{
    if(dep[x]>dep[y]) swap(x,y);
    int i,k=dep[y]-dep[x];
    FOR0(i,16) if(k&(1<<i)) y=f[y][i];
    if(x==y) return x;
    for(i=16;i>=0;i--)
    {
        if(f[x][i]&&f[y][i]&&f[x][i]!=f[y][i])
        {
            x=f[x][i];
            y=f[y][i];
        }
    }
    return f[x][0];
}

int cal(int x,int y,int z,int val)
{
    int i,k,ans=0,t=f[z][0];
    x=root[x];
    y=root[y];
    z=root[z];
    t=root[t];
    for(i=15;i>=0;i--)
    {
        k=!((val>>i)&1);
        int xx=a[x].c[k];
        int yy=a[y].c[k];
        int zz=a[z].c[k];
        int tt=a[t].c[k];
        if(a[xx].cnt+a[yy].cnt-a[zz].cnt-a[tt].cnt>0) ans|=1<<i;
        else k=!k;
        x=a[x].c[k];
        y=a[y].c[k];
        z=a[z].c[k];
        t=a[t].c[k];
    }
    return ans;
}

int main()
{
    while(scanf("%d%d",&n,&m)!=-1)
    {
        int i;
        FOR1(i,n) RD(d[i]),head[i]=-1;
        cnt=0; e=0;
        FOR1(i,n-1)
        {
            int u,v;
            RD(u,v);
            add(u,v); add(v,u);
        }
        clr(f,0);
        DFS(1,0);
        int j;
        for(i=1;i<=16;i++) FOR1(j,n)
        {
            f[j][i]=f[f[j][i-1]][i-1];
        }
        while(m--)
        {
            int x,y,z;
            RD(x,y,z);
            PR(cal(x,y,getLca(x,y),z));
        }
    }
}

  

HDU 4757 Tree(可持久化trie)的更多相关文章

  1. HDU.4757.Tree(可持久化Trie)

    题目链接 \(Description\) 给定一棵树,点有点权.\(Q\)次询问\(x,y,z\),求\(x\)到\(y\)的简单路径中,与\(z\)异或能得到的最大的数是多少. \(Solution ...

  2. HDU 4757 Tree 可持久化字典树 trie

    http://acm.hdu.edu.cn/showproblem.php?pid=4757 给出一棵树,每个节点有权值,每次查询节点 (u,v) 以及 val,问 u 到 v 路径上的某个节点与 v ...

  3. HDU 4757 Tree 可持久化字典树

    Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4757 Des ...

  4. HDU 4757 Tree(可持久化Trie+Tarjan离线LCA)

    Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total Su ...

  5. HDU 4757 Tree

    传送门 Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Prob ...

  6. HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)

    Problem Description   Zero and One are good friends who always have fun with each other. This time, ...

  7. HDU4757 Tree(可持久化Trie)

    写过可持久化线段树,但是从来没写过可持久化的Trie,今天补一补. 题目就是典型的给你一个数x,和一个数集,问x和里面的某个数xor起来的最大值是多少. 最原始的是数集是固定的,只需要对数集按照高到低 ...

  8. HDU 4757 Tree(可持续化字典树,lca)

    题意:询问树上结点x到结点y路上上的权值异或z的最大值. 任意结点权值 ≤ 2^16,可以想到用字典树. 但是因为是询问某条路径上的字典树,将字典树可持续化,字典树上的结点保存在这条路径上的二进制数. ...

  9. 可持久化Trie模板

    如果你了解过 01 Trie 和 可持久化线段树(例如 : 主席树 ).那么就比较好去可持久化 Trie 可持久化 Trie 当 01 Trie 用的时候能很方便解决一些原本 01 Trie 不能解决 ...

随机推荐

  1. Codeforces Round #284 (Div. 2)

    题目链接:http://codeforces.com/contest/499 A. Watching a movie You have decided to watch the best moment ...

  2. Dynamic Programming - Part2

    实现如下: public static void main(String[] args) { String squence1 = "ABCBDAB"; String squence ...

  3. NENU_CS_segment_tree

    单点更新 http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意:单点更新加减,区间查询求和. #include<cstdio> #define ...

  4. SSH无密码验证

    一.安装和启动SSH协议 sudo yum install ssh sudo yum install rsync service sshd restart 启动服务 (rsync是一个远程数据同步工具 ...

  5. 在centos 6.5 在virtual box 上 安装增强版工具

    centos 6.5 在virtual box 上 安装增强版工具: 出现:centos unable to find the source of your current linux kernel ...

  6. mysql 权限 备份

    mysqldump常用于MySQL数据库逻辑备份. 1.各种用法说明 A. 最简单的用法: mysqldump -uroot -pPassword [database name] > [dump ...

  7. mydate97时间控件最大值最小值限制及Javascript日期判断大小

    <script language="javascript" type="text/javascript" src="<%=basePath ...

  8. POJ 1222

    EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6196   Accepted: 40 ...

  9. iOS后台如何保持socket长连接和数据传输

    工程中使用tcp长连接来和服务端进行数据传输,在IOS平台上,由于苹果的后台机制,会有以下问题: 当程序退到后台的时候,所有线程被挂起,系统会回收所有的socket资源,那么socket连接就会被关闭 ...

  10. SQL Server 基础 之 GROUP BY子句

    GROUP BY 子句用于聚合信息 先看个实例,没有使用 GROUP BY 子句 SELECT SalesOrderID,OrderQty FROM Sales.SalesOrderDetail WH ...