HDU 4757
可持久化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的更多相关文章
- 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: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4757 Des ...
- 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: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Prob ...
- HDU.4757.Tree(可持久化Trie)
题目链接 \(Description\) 给定一棵树,点有点权.\(Q\)次询问\(x,y,z\),求\(x\)到\(y\)的简单路径中,与\(z\)异或能得到的最大的数是多少. \(Solution ...
- HDU 4757 可持久化trie树
首先如果给定一些数,询问这些数中哪个数^给定的数的值最大的话,我们可以建立一颗trie树,根连接的两条边分别为0,1,表示二进制下第15位,那么我们可以建立一颗trie树,每一条从根到叶子节点的链表示 ...
- HDU 4757 Tree(可持续化字典树,lca)
题意:询问树上结点x到结点y路上上的权值异或z的最大值. 任意结点权值 ≤ 2^16,可以想到用字典树. 但是因为是询问某条路径上的字典树,将字典树可持续化,字典树上的结点保存在这条路径上的二进制数. ...
- 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, ...
随机推荐
- Python协程(下)
停止子线程 如果一切正常,那么上面的例子很完美.可是,需要停止程序,直接ctrl+c,会抛出KeyboardInterrupt错误,我们修改一下主循环: try: while True: task = ...
- MySQL笔记(四)之内建函数
AVG() 函数 AVG 函数返回数值列的平均值.NULL 值不包括在计算中. 语法: SELECT AVG(列) FROM 表: COUNT() 函数 COUNT() 函数返回匹配指定条件的行数. ...
- luoguP3600 随机数生成器 期望概率DP + DP优化
这篇题解更像对他人题解的吐槽和补充? 考虑答案 $E[X] = \sum\limits_{i = 1}^{x} i P(X = i)$ $P(X = i)$不好求................(其实 ...
- Linux进程守护——Supervisor 使用记录
0.旁白 Supervisor是个父进程,你要守护的进程会以Supervisor的子进程形式存在,所以老子才可以管儿子 官网链接:http://supervisord.org/ [5.参数]那块不要看 ...
- String是最基本的数据类型吗?
不是, 基本数据类型包括:byte,short,int,long,float,double,boolean,char. 而String是类代表字符串,属于引用类型,所谓引用类型包括:类,接口,数组.. ...
- Rails -- 自动清除日志
在开发模式中,开发环境日志会越来越大,所以需要设置自动清理,省内存. 在 config/initializers中新建一个文件 clear_blog.rb 编写如下代码 if Rails.env.de ...
- Dual-voltage regulator meets USB-power needs
This Design Idea stems from the limited availability of IC voltage regulators that can meet key USB- ...
- OOW 2015 MYSQL
https://events.rainfocus.com/oow15/catalog/oracle.jsp?search.event=openworldEvent&search.mysql=d ...
- .Net4.0并行库介绍——Task
Task和ThreadPool的功能类似,可以用来创建一些轻量级的并行任务.对于将一个任务放进线程池 ThreadPool.QueueUserWorkItem(A); 这段代码用Task来实现 ...
- jdbc分页
分页是一个被讲到烂掉的话题,今天我再拾起来踹几脚吧 (Hibernate的分页做得很好很强大,用的人都知道 ,这个就不用再说了) 1.为什么要分页? 首先是数据量太大会影响查询和传输的性能,关键 ...