题意:n个点的树,Q次询问,询问u-v路径上的点的权值与z抑或的最大值。

先考虑,在一个区间上的问题,可以先建一个可持久化的Trie,然后每次询问,就和线段树的操作差不多,从最高位开始考虑选1还是选0。

在树上的话, 可以转化成 parent[LCA(u, v)] - u ,  parent[LCA(u, v)] - v,这两个区间的最大值。

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1e5 + ;
const int maxdep = ;
const int maxlog = ;
vector <int> G[maxn];
int idx, A[maxn];
//可持久化Trie, 初始状态val为0
int tree[maxn], lson[maxn * maxlog], rson[maxn * maxlog], val[maxn * maxlog];
int insert(int root, int x){ // x为每次插入的值
int newroot = idx++;
int tmp = newroot;
for (int i = ; i >= ; i--){
if (!(x & ( << i))){
lson[newroot] = idx++;
rson[newroot] = rson[root];
newroot = lson[newroot];
root = lson[root];
}else{
rson[newroot] = idx++;
lson[newroot] =lson[root];
newroot = rson[newroot];
root = rson[root];
}
val[newroot] = val[root] + ;
}
return tmp;
}
int query (int ua, int ub, int z, int d){
if (d == -){
return ;
}
int res = ;
if (z & ( << d)){
if (val[lson[ub]] - val[lson[ua]]){
res ^= << d;
res += query(lson[ua], lson[ub], z, d-);
}else{
res = query(rson[ua], rson[ub], z, d-);
}
}else{
if (val[rson[ub]] - val[rson[ua]]){
res ^= << d;
res += query(rson[ua], rson[ub],z, d-);
}else{
res = query(lson[ua], lson[ub], z, d-);
}
}
return res;
}
int parent[maxdep][maxn], dep[maxn];
void dfs(int u, int father){
parent[][u] = father;
dep[u] = dep[father] + ;
tree[u] = insert(tree[father], A[u]);
for (int v: G[u]){
if (v != father){
dfs(v, u);
}
}
}
void lca_init(int n){
dfs(, );
for (int k = ; k + < maxdep; k++){
for (int v = ; v <= n; v++){
if (parent[][v] <= ){
parent[k+][v] = -;
}else{
parent[k+][v] = parent[k][parent[k][v]];
}
}
}
}
int lca(int u, int v){
if (dep[u] > dep[v]){
swap(u, v);
}
for (int k = ; k < maxdep; k++){
if ((dep[v] - dep[u]) >> k & ){
v = parent[k][v];
}
}
if (u == v){
return u;
}
for (int k = maxdep-; k >= ; k--){
if (parent[k][u] != parent[k][v]){
u = parent[k][u];
v = parent[k][v];
}
}
return parent[][u];
}
void init(){
for (int i = ; i < maxn; i++){
G[i].clear();
}
idx = ;
memset(val, , sizeof (val));
}
void debug(int x, int i){
if (val[lson[x]]){
printf("%d,0 ", i);
debug(lson[x], i-);
} if (val[rson[x]]){
printf("%d,1 ", i);
debug(rson[x], i-);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
int n, m;
while (~ scanf ("%d%d", &n, &m)){
init();
for (int i = ; i <= n; i++){
scanf ("%d", A+i);
}
for (int i = ; i < n-; i++){
int u, v;
scanf ("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(, );
lca_init(n);
for (int i = ; i < m; i++){
int u, v, c;
scanf ("%d%d%d", &u, &v, &c);
int tmp = parent[][lca(u, v)];
printf("%d\n", max(query(tree[tmp], tree[u], c, ), query(tree[tmp], tree[v], c, )));
}
}
return ;
}

HDU4757--Tree 可持久化trie + LCA的更多相关文章

  1. HDU4757 Tree(可持久化Trie)

    写过可持久化线段树,但是从来没写过可持久化的Trie,今天补一补. 题目就是典型的给你一个数x,和一个数集,问x和里面的某个数xor起来的最大值是多少. 最原始的是数集是固定的,只需要对数集按照高到低 ...

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

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

  3. Hdu-4757 Tree(可持久化字典树+lca)

    题目链接:点这 我的github地址:点这     Problem Description   Zero and One are good friends who always have fun wi ...

  4. hdu4757(可持久化 Trie )

    hdu4757 题意 给出一棵树,每个节点有权值,每次查询节点 \((u, v)\) 以及 \(x\) ,问 \(u\) 到 \(v\) 路径上的某个节点与 \(x\) 异或最大的值是多少. 分析 T ...

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

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

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

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

  7. HDU 6191 Query on A Tree ( 2017广西邀请赛 && 可持久化Trie )

    题目链接 题意 : 给你一棵树.树上的每个点都有点权.之后有若干次问询.每次问询给出一个节点编号以及一个整数 X .问你以给出节点为根的子树中哪个节点和 X 异或最大.输出这个值 分析 : 看到这种树 ...

  8. 可持久化 trie 的简单入门

    可持久化 $trie$  ....又是一个表里不一的东西..... 可持久化 $trie$  的介绍: 和主席树类似的,其实可持久化就是体现在前缀信息的维护上(搞不懂这怎么就叫做可持久化了...) $ ...

  9. BZOJ4477 JSOI2015字符串树(可持久化trie)

    树上建可持久化trie即可,有点过于裸了.darkbzoj过了然而在bzoj一直wa,不知道哪有锅. #include<iostream> #include<cstdio> # ...

随机推荐

  1. [转] C语言多维数组与多级指针

    http://c.biancheng.net/cpp/html/477.html 多维数组与多级指针也是初学者感觉迷糊的一个地方.超过二维的数组和超过二级的指针其实并不多用.如果能弄明白二维数组与二级 ...

  2. Java基础知识强化之IO流笔记19:FileOutputStream的三个write方法

    1. FileOutputStream的三个write方法:  void write(byte[] buffer)           Writes the entire contents of th ...

  3. JS HTML 单引号与双引号

    JS中,单引号和双引号其实没啥区别,看你自己习惯了. 但若双引号中再使用双引号,我们可采取"外双内单"或者"外单内双"的格式,当然如果需要的是双引号本身,则只能 ...

  4. codevs 1183 泥泞的道路 (二分+SPFA+差分约束)

    /* 二分答案(注意精度) 对于每一个答案 有(s1+s2+s3...)/(t1+t2+t3...)>=ans 时符合条件 这时ans有变大的空间 对于上述不等式如果枚举每一条路显得太暴力 化简 ...

  5. wpf的学习日志(二)

    window演示基础(windows presentation Foundation)用于windowsw图形显示系统 InitializeComponent()方法的工作就是system.windo ...

  6. Web项目练习总结(错误校正篇)

    老师布置任务,从SVN上弄个项目来练练手,熟悉下过程. myeclipse安装SVN 然后把MobileManageSys下下来 然后漫长的等待... 然后配置数据库,导入,这里用的是SQLyog,其 ...

  7. HDU5301

    题意:给n*m的矩形区域,剔除其中1*1的方块,然后用不同矩形块填充整个矩形区域,求需要的矩形块最大面积的最小值. 思路:先判把矩形矫正,然后特殊处理边值为奇数,且在中心点的情况,最后处理障碍在其他位 ...

  8. 织梦DeDeCms列表分页和内容页分页错位解决办法

    文章页分页代码在这里/include/arc.archives.class.php列表页分页/include/arc.listview.class.php 很多入门的站长会碰到这样的问题,织梦的通病, ...

  9. winapi获取鼠标位置

    using System; using System.Drawing; using System.Runtime.InteropServices; using System.Threading; na ...

  10. 获取fragment中的控件的写法

    package com.example.baoxiu.fragment;import com.example.baoxiu.R;import com.example.baoxiu.Register;i ...