Problem Description
  Zero and One are good friends who always have fun with each other. This time, they decide to do something on a tree which is a kind of graph that there is only one path from node to node. First, Zero will give One an tree and every node in this tree has a value. Then, Zero will ask One a series of queries. Each query contains three parameters: x, y, z which mean that he want to know the maximum value produced by z xor each value on the path from node x to node y (include node x, node y). Unfortunately, One has no idea in this question. So he need you to solve it.
 
Input
  There are several test cases and the cases end with EOF. For each case:

The first line contains two integers n(1<=n<=10^5) and m(1<=m<=10^5), which are the amount of tree’s nodes and queries, respectively.

The second line contains n integers a[1..n] and a[i](0<=a[i]<2^{16}) is the value on the ith node.

The next n–1 lines contains two integers u v, which means there is an connection between u and v.

The next m lines contains three integers x y z, which are the parameters of Zero’s query.

 
Output
  For each query, output the answer.
 
题目大意:给你一颗n个点的树,每个点有一个权值。然后有m个询问,问从x到y的简单路径中,权值 xor z最大是多少。
思路:可持久化的0-1字典树,每个点在父节点的历史版本上新建一棵字典树,字典树上的每个结点给一个值记录从这个结点到树的根节点,有多少个权值会经过这个字典树上的结点。询问的时候在字典树上奏即可。由于a[i]<2^16,那么字典树的深度最大为16,空间复杂度为O(16 * n)。
PS:tarjan果然要比RMQ快啊。
PS2:数据保障z<2^16,虽然题目没讲……
 
代码(1265MS):
 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std; const int MAX = ;
const int MAXN = * MAX;
const int MAXE = * MAXN; int head[MAXN], weight[MAXN], fa[MAX];
bool vis[MAX];
int to[MAXE], next[MAXE], id[MAXE];
int n, m, ecnt; inline void init() {
memset(head, , sizeof(head));
memset(vis, , sizeof(vis));
for(int i = ; i <= n; ++i) fa[i] = i;
ecnt = ;
} inline void add_edge(int u, int v, int i) {
to[ecnt] = v; id[ecnt] = i; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; id[ecnt] = i; next[ecnt] = head[v]; head[v] = ecnt++;
} struct QUERY {
int x, y, lca, z;
void read(int i) {
scanf("%d%d%d", &x, &y, &z);
add_edge(x + n, y + n, i);
}
} Query[MAX]; int get_set(int x) {
return fa[x] == x ? x : fa[x] = get_set(fa[x]);
} void dfs_LCA(int u, int f) {
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(v == f) continue;
dfs_LCA(v, u);
fa[v] = u;
}
vis[u] = true;
for(int p = head[u + n]; p; p = next[p]) {
int v = to[p] - n;
if(vis[v]) Query[id[p]].lca = get_set(v);
}
} struct Node {
int go[], cnt;
} tree[ * MAX];
int root[MAX], Tcnt; void init_tree() {
Tcnt = ; root[] = ;
} int insert(int x, int val) {
tree[Tcnt] = tree[x];
int ret = x = Tcnt++;
for(int i = ; i >= ; --i) {
int idx = (val >> i) & , t = Tcnt++;
tree[t] = tree[tree[x].go[idx]];
++tree[t].cnt;
tree[x].go[idx] = t;
x = t;
}
return ret;
} void dfs_build(int u, int f) {
root[u] = insert(root[f], weight[u]);
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(v == f) continue;
dfs_build(v, u);
}
} int query(int x, int y, int lca, int val) {
int ret = , ret_lca = weight[lca] ^ val;
x = root[x], y = root[y], lca = root[lca];
for(int i = ; i >= ; --i) {
int idx = !((val >> i) & );
int cnt = tree[tree[x].go[idx]].cnt + tree[tree[y].go[idx]].cnt - * tree[tree[lca].go[idx]].cnt;
if(cnt > ) ret |= ( << i);
else idx = !idx;
x = tree[x].go[idx], y = tree[y].go[idx], lca = tree[lca].go[idx];
}
return max(ret, ret_lca);
} int main() {
while(scanf("%d%d", &n, &m) != EOF) {
for(int i = ; i <= n; ++i) scanf("%d", &weight[i]);
init();
for(int i = ; i < n; ++i) {
int u, v;
scanf("%d%d", &u, &v);
add_edge(u, v, );
}
for(int i = ; i <= m; ++i) Query[i].read(i);
dfs_LCA(, );
init_tree();
dfs_build(, );
for(int i = ; i <= m; ++i)
printf("%d\n", query(Query[i].x, Query[i].y, Query[i].lca, Query[i].z));
}
}

HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)的更多相关文章

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

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

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

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

  3. HDU 4758——Walk Through Squares——2013 ACM/ICPC Asia Regional Nanjing Online

    与其说这是一次重温AC自动机+dp,倒不如说这是个坑,而且把队友给深坑了. 这个题目都没A得出来,我只觉得我以前的AC自动机的题目都白刷了——深坑啊. 题目的意思是给你两个串,每个串只含有R或者D,要 ...

  4. HDU 4749 Parade Show 2013 ACM/ICPC Asia Regional Nanjing Online

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目大意:给一个原序列N,再给出一个序列M,问从N中一共可以找出多少个长度为m的序列,序列中的数 ...

  5. [2013 ACM/ICPC Asia Regional Nanjing Online C][hdu 4750]Count The Pairs(kruskal + 二分)

    http://acm.hdu.edu.cn/showproblem.php?pid=4750 题意: 定义f(u,v)为u到v每条路径上的最大边的最小值..现在有一些询问..问f(u,v)>=t ...

  6. HDU 4751 Divide Groups 2013 ACM/ICPC Asia Regional Nanjing Online

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4751 题目大意:判断一堆人能否分成两组,组内人都互相认识. 解题思路:如果两个人不是相互认识,该两人之 ...

  7. hdu 4751 Divide Groups bfs (2013 ACM/ICPC Asia Regional Nanjing Online 1004)

    SDUST的训练赛 当时死磕这个水题3个小时,也无心去搞其他的 按照题意,转换成无向图,预处理去掉单向的边,然后判断剩下的图能否构成两个无向完全图(ps一个完全图也行或是一个完全图+一个孤点) 代码是 ...

  8. HDU4753 Fishhead’s Little Game——2013 ACM/ICPC Asia Regional Nanjing Online

    今天比赛又是做得好水的.被狂虐啊. 比赛两个多小时一直没出题,遒遒最先交的若干发都wa了.T_T 我独自在一遍苦思了1006这个题,还好最后把这个题目A掉了,不然又是深坑队友. 题目的意思我就不多说了 ...

  9. hduoj 4710 Balls Rearrangement 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4710 Balls Rearrangement Time Limit: 6000/3000 MS (Java/Ot ...

随机推荐

  1. sed实现路径替换

    shell和sed忘得差不多了,现在更喜欢用python notebook,可以自动补充,所以很方便.但是记得以前用过这个的,试了几次不成功,搜了一下,这几个地方给的比较清晰,尤其是路径替换. 以下内 ...

  2. Python 学习笔记(五)常用函数

    Python内建函数 四舍五入: round() 绝对值: abs() >>> round(1.543,2) 保留两位小数,四舍五入为1.54 1.54 >>> r ...

  3. javascript 六种基本数据类型转换

    javascript 六种基本数据类型转换 1.显式转换 通过手动进行类型转换,Javascript提供了以下转型函数: 转换为数值类型:Number(mix).parseInt(string,rad ...

  4. 网页后缀html、htm、shtml、shtm有什么区别?

    每一个网页或者说是web页都有其固定的后缀名,不同的后缀名对应着不同的文件格式和不同的规则.协议.用法,最常见的web页的后缀名是.html和.htm,但这只是web页最基本的两种文件格式,今天我们来 ...

  5. logback.xml模板详解

    <?xml version="1.0" encoding="UTF-8"?> <!-- 配置文件每隔1分钟,就检查更新 --> < ...

  6. php第三节(运算符)

    <?php //算术运算符 + - * / % //++ 前加加 先做加运算后座赋值运算 后加加 先做赋值运算后座加运算 //-- 前减减 先做加运算后座赋值运算 后减减 先做赋值运算后座加运算 ...

  7. 分页离线条件查询 页面响应500 后端未报异常 list集合有数据

    如果 使用同一个Hibernate的DetachedCriteria离线条件查询对象同时查询“过滤后条数” 和 “过滤后的数据集合”,那么查询记录数时需要设置聚合函数条件并且 使用聚合函数  代码要在 ...

  8. JavaSE 第二次学习随笔(三)

    * 常见异常 * 数组越界异常 * 空指针异常 * * * 特点: 当程序出现异常的时候, 程序会打印异常信息并中断程序 * 所以当同时出现多个异常的时候只能执行第一个, 后边的用不到 * * 单异常 ...

  9. hadoop生态搭建(3节点)-04.hadoop配置

    如果之前没有安装jdk和zookeeper,安装了的请直接跳过 # https://www.oracle.com/technetwork/java/javase/downloads/java-arch ...

  10. Scrapy进阶

    当我们使用scrapy框架爬取网站的时候,我们会有一个入口的url,一个名为start_urls,我们爬取的第一个网页是从这一开始的. 需求: 现在我们有一个这样的需求,比如说我们对起始的URL有一个 ...