题目链接

\(Description\)

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

\(Solution\)

对于给定数集的询问,我们可以建Trie树,从高位到低位贪心地走(能走优的就走)。

同树上的主席树一样,利用父节点的根节点建树,就是可持久化Trie。

令\(w=LCA(u,v)\)。因为只是xor一个数,所以用\(u,v,w\)三个点的根节点就可以了,最后再判断一下\(w\)是否可能更优(不需要\(fa[w]\))。

在\(u,v,w\)三棵Trie上走,若\(sz[u]+sz[v]-2*sz[w]>0\)则能走。

区间询问同理也可以做。

//1201MS	30704K
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
#define BIT 15
const int N=1e5+5; int Enum,H[N],nxt[N<<1],to[N<<1],A[N],root[N],fa[N],dep[N],sz[N],son[N],top[N];
struct Trie
{
#define S N*20//N*18为什么不够啊
int tot,sz[S],son[S][2]; inline int New_Node()
{
++tot, sz[tot]=0, son[tot][0]=son[tot][1]=0;
return tot;
}
void Insert(int x,int y,int v)
{
for(int i=BIT; ~i; --i)
{
int c=v>>i&1;
son[x][c]=New_Node(), son[x][c^1]=son[y][c^1];
x=son[x][c], y=son[y][c];
sz[x]=sz[y]+1;//上面根节点的sz不需要加
}
}
int Query(int x,int y,int w,int v)
{
int res=0,tmp=A[w]^v;
w=root[w];
for(int i=BIT; ~i; --i)
{
int c=(v>>i&1)^1;
if(sz[son[x][c]]+sz[son[y][c]]-2*sz[son[w][c]]>0)
x=son[x][c], y=son[y][c], w=son[w][c], res|=1<<i;
else
c^=1, x=son[x][c], y=son[y][c], w=son[w][c];
}
return std::max(res,tmp);
}
}T; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
inline int LCA(int u,int v)
{
while(top[u]!=top[v]) dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]];
return dep[u]<dep[v]?u:v;
}
void DFS1(int x)
{
int mx=0; sz[x]=1;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x])
{
fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v];
if(sz[v]>mx) mx=sz[v], son[x]=v;
}
}
void DFS2(int x,int tp)
{
top[x]=tp;
T.Insert(root[x]=T.New_Node()/**/,root[fa[x]],A[x]);
if(son[x])
{
DFS2(son[x],tp);
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x] && v!=son[x]) DFS2(v,v);
}
} int main()
{
int n;
while(~scanf("%d",&n))
{
T.tot=Enum=0, memset(H,0,sizeof H);
memset(son,0,sizeof son);//!
// memset(root,0,sizeof root); int Q=read();
for(int i=1; i<=n; ++i) A[i]=read();
for(int i=1; i<n; ++i) AE(read(),read());
DFS1(1), DFS2(1,1);
for(int u,v; Q--; ) u=read(),v=read(),printf("%d\n",T.Query(root[u],root[v],LCA(u,v),read()));
}
return 0;
}

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

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

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

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

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

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

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

  4. HDU 4757 Tree(可持久化trie)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4757 题意:给出一棵树,节点有权值.每次询问x到y的路径上与z抑或的最大值. 思路:可持久化trie. ...

  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. IAR各个历史版本的下载地址

    http://supp.iar.com/Updates/?product=EWarm 点击进入上述链接,拉到最底部,点击old version即可见到所有的历史版本!!!

  2. UML和模式应用1: 面向对象的分析与设计

    1.基本术语说明 items note OOA/D  面向对象的分析与设计 UML 描述.构造和文档化系统制品的可视化语言 模式 问题解决方案的公式 2. 本书的主要内容 本书的主旨是对应用了UML和 ...

  3. python标准库之secrets

    secrets secrets是python3.6加入到标准库的,使用secrets模块,可以生成适用于处理机密信息(如密码,帐户身份验证,安全令牌)的加密强随机数. 导入 import secret ...

  4. How to scroll down with Phantomjs to load dynamic content

    page.open('http://example.com/?q=houston', function () { // Checks for bottom div and scrolls down f ...

  5. mysql系列二、mysql内部执行过程

    向MySQL发送一个请求的时候,MySQL到底做了什么 客户端发送一条查询给服务器. 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器端进行SQL解析.预 ...

  6. [转]解决win7 64位操作系统下安装PL/SQL后连接报错问题: make sure you have the 32 bits oracle client installed

    1. 在Oracle官网(http://www.oracle.com/technetwork/topics/winsoft-085727.html)下载文件: instantclient-basic- ...

  7. oracle 分区 查询

    显示数据库所有分区表的信息:DBA_PART_TABLES 显示当前用户可访问的所有分区表信息:ALL_PART_TABLES 显示当前用户所有分区表的信息:USER_PART_TABLES 显示表分 ...

  8. LeetCode(4):两个排序数组的中位数

    Hard! 题目描述: 有两个大小为 m 和 n 的排序数组 nums1 和 nums2 . 请找出两个排序数组的中位数并且总的运行时间复杂度为 O(log (m+n)) . 示例 1: nums1 ...

  9. 目标检测-ssd

    intro: ECCV 2016 Oral arxiv: http://arxiv.org/abs/1512.02325 paper: http://www.cs.unc.edu/~wliu/pape ...

  10. hdu4533 线段树维护分段函数

    更新:x1,y1,x2,y2不用long long 会wa.. #include<iostream> #include<cstring> #include<cstdio& ...