可持久化trie树。不会可持久化数据结构的话推荐先看陈立杰的论文。先掌握可持久化线段树和可持久化trie树。

//可持久化trie树,题目已知一棵树,每个点有点权,询问一对点路径上点权与给定值异或的最大值
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100100
using namespace std; struct Edge{
int v,next;
}edge[N*2]; int head[N],val[N],cnt,n,m; void addedge(int u,int v){
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].v=u;
edge[cnt].next=head[v];
head[v]=cnt++;
} struct Trie{
int go[2],cnt;
}trie[N*17];
int root[N],tot; int insert(int id,int num){
int p=++tot,tem=p;
trie[p]=trie[id];
for(int i=15;i>=0;i--){
int tmp=(num>>i)&1;
trie[++tot]=trie[trie[p].go[tmp]];
trie[tot].cnt++;
trie[p].go[tmp]=tot;
p=tot;
}
return tem;
} void dfs(int u,int father){
root[u]=insert(root[father],val[u]);
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(v==father)continue;
dfs(v,u);
}
} struct Query{
int v,id,w,next;
}query[N*2]; int head2[N],cnt2,f[N],lca[N],ans[N];
bool flag[N]; void addedge2(int u,int v,int w,int id){
query[cnt2].v=v;
query[cnt2].w=w;
query[cnt2].id=id;
query[cnt2].next=head2[u];
head2[u]=cnt2++;
query[cnt2].v=u;
query[cnt2].w=w;
query[cnt2].id=id;
query[cnt2].next=head2[v];
head2[v]=cnt2++;
} int find(int u){
if(u==f[u]) return u;
return f[u]=find(f[u]);
} void tarjan(int u,int father){
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(v==father) continue;
tarjan(v,u);
f[v]=u;
}
flag[u]=1;
for(int i=head2[u];i!=-1;i=query[i].next){
int v=query[i].v;
if(flag[v]){
lca[query[i].id]=find(v);
}
}
} int findans(int u,int v,int LCA,int num){
int p1=root[u],p2=root[v],p3=root[LCA],ans_tmp=0;
for(int i=15;i>=0;i--){
int tmp=(num>>i)&1;
int sum=trie[trie[p1].go[!tmp]].cnt+trie[trie[p2].go[!tmp]].cnt-2*trie[trie[p3].go[!tmp]].cnt;
if(sum>0){
p1=trie[p1].go[!tmp];
p2=trie[p2].go[!tmp];
p3=trie[p3].go[!tmp];
ans_tmp+=1<<i;
}
else{
p1=trie[p1].go[tmp];
p2=trie[p2].go[tmp];
p3=trie[p3].go[tmp];
}
}
return max(ans_tmp,num^val[LCA]);
} void solve(){
for(int i=1;i<=n;i++)
for(int j=head2[i];j!=-1;j=query[j].next){
int id=query[j].id;
if(ans[id]!=-1)continue;
ans[id]=findans(i,query[j].v,lca[id],query[j].w);
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
} void init(){
memset(head,-1,sizeof(head));
memset(head2,-1,sizeof(head2));
memset(ans,-1,sizeof(ans));
cnt=cnt2=0;
} int main(){
int u,v,w;
while(scanf("%d %d",&n,&m)!=EOF){
init();
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
for(int i=1;i<n;i++){
scanf("%d %d",&u,&v);
addedge(u,v);
}
root[0]=0;
trie[0].go[0]=trie[0].go[1]=0;
trie[0].cnt=0;
tot=0;
dfs(1,0);
for(int i=1;i<=m;i++){
scanf("%d %d %d",&u,&v,&w);
addedge2(u,v,w,i);
}
for(int i=1;i<=n;i++) f[i]=i;
memset(flag,0,sizeof(flag));
tarjan(1,0);
solve();
}
return 0;
}

HDU 4757的更多相关文章

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

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

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

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

  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

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

  5. HDU 4757 Tree

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

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

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

  7. HDU 4757 可持久化trie树

    首先如果给定一些数,询问这些数中哪个数^给定的数的值最大的话,我们可以建立一颗trie树,根连接的两条边分别为0,1,表示二进制下第15位,那么我们可以建立一颗trie树,每一条从根到叶子节点的链表示 ...

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

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

  9. 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, ...

随机推荐

  1. FileZilla提权的过程

    话不多说,我们直接操作! 首先我们通过 webshell 找到 FileZilla 的文件目录,找到 FileZilla Server Interface.xml 文件,打开.我们可以看到它的连接地址 ...

  2. [HihoCoder1169]猜单词

    题目大意: 给你一个数列,问区间[l,r]内与k最接近的数与k的差是多少. 思路: 将数列中的数和询问的数先从小到大排序, 从小到大枚举每个数,如果是数列上的,就加到线段树中, 如果是询问中的,就在线 ...

  3. 区间DP--凸多边形三角剖分

    给定一个具有N(N<50)个顶点(从1到N编号)的凸多边形,每个顶点的权均已知.问如何把这个凸多边形划分成N-2个互不相交的三角形,使得这些三角形顶点的权的乘积之和最小? 输入文件:第一行 顶点 ...

  4. [转]Android之Activity的几种跳转方式

     1.显示调用方法 Intent intent=new Intent(this,OtherActivity.class);  //方法1 Intent intent2=new Intent(); in ...

  5. 使用Dragablz快速构建Chrome样式的可拖拽分离的Tab页程序

    今天发现了一个可以快速实现类似于Chrome方式的可拖拽分离的Tab页程序Dragablz.它可以实现动态创建,删除Tab页,并支持拖拽后形成独立窗口和窗口合并.   使用起来还是非常方便的. < ...

  6. Delphi插件创建、调试与使用应用程序扩展

    Delphi插件创建.调试与使用应用程序扩展 翻译 : MiracleZ  有没有使用过Adobe Photoshop?如果用过,你就会对插件的概念比较熟悉.对外行人来说,插件仅仅是从外部提供给应用程 ...

  7. LINQ中的动态排序

    使用Linq动态属性排序 使用反射: public static Func<T,Tkey> DynamicLambda<T, Tkey>(string propertyName ...

  8. 修改Linux默认启动级别或模式

    在Linux中有7种启动级别,默认是X-Window,像是Windows的窗口模式,而Linux的操作和配置一般我们都采用输入命令的方式来完成,像DOS操作系统一样,如何让Linux一启动就进入这种模 ...

  9. Caffe简单入门 AI

    https://yq.aliyun.com/articles/112207?spm=5176.100239.bloglist.58.wN003U

  10. Wix使用整理(二)

    1)         安装卸载时进行日志记录 Wix 制作的 Installer 的调试很麻烦,没有直接的 Bug 工具,可以通过记录安装日志的方式进行间接调试.命令为 msiexec /i pack ...