题目链接: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. BZOJ 2820 YY的GCD

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2820 有种方法是枚举质数然后用BZOJ2301来做但是超时了... 具体式子大概张这样: ...

  2. [noip2005提高]过河 dp

    由于L的范围到了109,用普通dp做肯定是不成了: 可以观察到M的数量很小,dp在转移的过程中有大量的无用转移: 可以想到压缩范围,问题是如何压缩,观察若S=9,T=10时,能到达的点,9,10,18 ...

  3. nsight 初级使用指南

    1.安装,没有什么特殊设置 2.打开vs,编译生成你需要分析的.exe,在vs上方菜单,有nsight menu, choose Start Graphics Debugging. 3.在弹出对话框中 ...

  4. Sqli-labs less 58

    Less-58 执行sql语句后,并没有返回数据库当中的数据,所以我们这里不能使用union联合注入,这里使用报错注入. Payload:http://127.0.0.1/sqli-labs/Less ...

  5. 【四】php字符串操作

    1.trim函数,我们队trim函数并不陌生,用于去除字符串两头的空白符.php的trim方法也可以做到这一点,但是还可以使用第二个参数,用于规定你在两头去掉什么.php中还有 ltrim 和 rtr ...

  6. 【C++】指针数组和数组指针

    首先的首先,稍微抱怨一下阿里今天的严重失误.说好的晚六点笔试,说好的务必提前半小时到场.六点十五的时候告诉闷在一个大教室里躁动的我们“今天七点半开考,大家先回去吧,七点半再过来”,满脸黑线…等到七点半 ...

  7. HDU 4006 The kth great number(multiset(或者)优先队列)

    题目 询问第K大的数 //这是我最初的想法,用multiset,AC了——好吧,也许是数据弱也有可能 //multiset运用——不去重,边插入边排序 //iterator的运用,插入的时候,如果是相 ...

  8. MYSQL 遭遇 THE TOTAL NUMBER OF LOCKS EXCEEDS THE LOCK TABLE SIZE

    今天进行MySql 一个表数据的清理,经过漫长等待后出现 The total number of locks exceeds the lock table size 提示.以为是table_cache ...

  9. JDBC资料集

    1.基本的JDBC概念: http://dev.mysql.com/doc/refman/5.1/zh/connectors.html#cj-basic-jdbc 2.JSP&Servlet学 ...

  10. Codeforces Round #259 (Div. 2) C - Little Pony and Expected Maximum (数学期望)

    题目链接 题意 : 一个m面的骰子,掷n次,问得到最大值的期望. 思路 : 数学期望,离散时的公式是E(X) = X1*p(X1) + X2*p(X2) + …… + Xn*p(Xn) p(xi)的是 ...