HDU.4757.Tree(可持久化Trie)
\(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)的更多相关文章
- HDU 4757 Tree 可持久化字典树 trie
http://acm.hdu.edu.cn/showproblem.php?pid=4757 给出一棵树,每个节点有权值,每次查询节点 (u,v) 以及 val,问 u 到 v 路径上的某个节点与 v ...
- HDU 4757 Tree 可持久化字典树
Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4757 Des ...
- HDU 4757 Tree(可持久化Trie+Tarjan离线LCA)
Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total Su ...
- HDU 4757 Tree(可持久化trie)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4757 题意:给出一棵树,节点有权值.每次询问x到y的路径上与z抑或的最大值. 思路:可持久化trie. ...
- HDU 4757 Tree
传送门 Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Prob ...
- 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, ...
- HDU4757 Tree(可持久化Trie)
写过可持久化线段树,但是从来没写过可持久化的Trie,今天补一补. 题目就是典型的给你一个数x,和一个数集,问x和里面的某个数xor起来的最大值是多少. 最原始的是数集是固定的,只需要对数集按照高到低 ...
- HDU 4757 Tree(可持续化字典树,lca)
题意:询问树上结点x到结点y路上上的权值异或z的最大值. 任意结点权值 ≤ 2^16,可以想到用字典树. 但是因为是询问某条路径上的字典树,将字典树可持续化,字典树上的结点保存在这条路径上的二进制数. ...
- 可持久化Trie模板
如果你了解过 01 Trie 和 可持久化线段树(例如 : 主席树 ).那么就比较好去可持久化 Trie 可持久化 Trie 当 01 Trie 用的时候能很方便解决一些原本 01 Trie 不能解决 ...
随机推荐
- MR目录结构
D:\MRData\MR\MRS\2017-05-25\TD-LTE_MRS_ZTE_OMC1_20170425000000.zip 每个zip中包含若干FDD-LTE_MRS_OMC1_28163_ ...
- python内存数据库pydblite
Pure-Python engine 最近由于项目开发中发现python informixDB模块对多线程的支持非常不好,当开启两个线程同时连接informix数据库的时候,数据库会报错,显示SQL ...
- lnmp使用socket方式连接nginx优化php-fpm性能
lnmp使用socket方式连接nginx优化php-fpm性能 Nginx连接fastcgi的方式有2种:TCP和unix domain socket 什么是Unix domain socket?- ...
- Go语言规格说明书 之 结构体类型(Struct types)
go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...
- HashMap Hashtable LinkedHashMap 和TreeMap
Map主要用于存储健值对,根据键得到值,因此不允许键重复(重复了覆盖了),但允许值重复.Hashmap 是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的 ...
- Python-CSS进阶
0. 什么时候该用什么布局 <!-- 定位布局: 以下两种布局不易解决的问题, 盒子需要脱离文档流处理 --> <!-- 浮动布局: 一般有block特性的盒子,水平排列显示 --& ...
- Windows服务项目打包成安装包(Windows服务)-----------VS2017项目程序打包成.msi或者.exe
VS2017项目程序打包成.msi或者.exe Windows服务项目使用VS2017项目程序打包成.msi或者.exe安装包 项目打包成安装包(Windows服务) 1.安装打包插件:Microso ...
- cf276E 两棵线段树分别维护dfs序和bfs序,好题回头再做
搞了一晚上,错了,以后回头再来看 /* 对于每次更新,先处理其儿子方向,再处理其父亲方向 处理父亲方向时无法达到根,那么直接更新 如果能达到根,那么到兄弟链中去更新,使用bfs序 最后,查询结点v的结 ...
- (二)使用CXF开发WebService服务器端接口
CXF作为java领域主流的WebService实现框架,Java程序员有必要掌握它. CXF主页:http://cxf.apache.org/ 简介:百度百科 今天的话,主要是用CXF来开发下Web ...
- Slave SQL_THREAD如何重放Relay log
复制的介绍: 根据日志定义的模式不一样,可以分为:Statement(SBR)模式,Row(RBR)格式或者是MIXED格式,记录最小的单位是一个Event,binlog日志前4个字节是一个magic ...