Hdu-4757 Tree(可持久化字典树+lca)
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.
题意:给一棵带权树,每次询问树上一条链上(x 到 y)的所有权值xor z的最大值。
思路:可持久化字典树+lca
不能用lca的倍增算法,会t,
关于lca可以看这个:https://www.cnblogs.com/zhouzhendong/p/7256007.html
/*
data:2018.04.26
author:gswycf
link:http://acm.hdu.edu.cn/showproblem.php?pid=4825
accout:tonysave
*/
#define ll long long
#define IO ios::sync_with_stdio(false);
#define maxn 100005
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<vector>
using namespace std;
class Node{
public:
int cnt,ls,rs;
};
int n,m,cnt,aa,bb;
Node tr[32*maxn];
int weight[maxn];int root[maxn];int deep[maxn],f[maxn][31];
vector<int> g[maxn];
inline void init()
{
memset(tr,0,sizeof(tr));
memset(weight,0,sizeof(weight));
memset(root,0,sizeof(root));
memset(deep,0,sizeof(deep));
memset(f,0,sizeof(f));
cnt=0;
for(int i=0;i<=n;i++)
g[i].clear();
}
int in(int pre,int x,int deep)
{
int num=++cnt;
tr[num]=tr[pre];
tr[num].cnt=tr[pre].cnt+1;
if(deep<0)return num;
if(!((x>>deep)&1))tr[num].ls=in(tr[pre].ls,x,deep-1);
else tr[num].rs=in(tr[pre].rs,x,deep-1);
return num;
}
int query(int l,int r,int x,int deep)
{
if(deep<0)return 0;
if(!((x>>deep)&1))
{
if(tr[tr[r].rs].cnt>tr[tr[l].rs].cnt)return (1<<deep)+query(tr[l].rs,tr[r].rs,x,deep-1);
else return query(tr[l].ls,tr[r].ls,x,deep-1);
}
else
{
if(tr[tr[r].ls].cnt>tr[tr[l].ls].cnt)return (1<<deep)+query(tr[l].ls,tr[r].ls,x,deep-1);
else return query(tr[l].rs,tr[r].rs,x,deep-1);
}
}
void bfs(int node,int fa)
{
root[node]=in(root[fa],weight[node],16);
f[node][0]=fa;deep[node]=deep[fa]+1;
for(int i=0;i<g[node].size();i++)
{
if(g[node][i]!=fa)
bfs(g[node][i],node);
}
}
inline void init2()
{
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
}
int lca(int a,int b,int c)
{
if(deep[a]>deep[b])swap(a,b);
int d=deep[b]-deep[a];
for(int i=0;i<30;i++)
if((1<<i)&d)b=f[b][i];
if(a==b)return a;
for(int i=29;i>=0;i--)
{
if(f[a][i]!=f[b][i])
a=f[a][i],b=f[b][i];
}
b=f[b][0];
return b;
}
int main()
{
int a,b,c;
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=1;i<=n;i++)scanf("%d",&weight[i]);
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
g[a].push_back(b);
g[b].push_back(a);
}
bfs(1,0);init2();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
int k=lca(a,b,c);
printf("%d\n",max(query(root[k-1],root[a],c,16),
query(root[k-1],root[b],c,16)));
}
}
}
/*
3 4
1 2 3
1 2
1 3
2 2 2
2 3 1
1 3 1
3 2 1
*/
Hdu-4757 Tree(可持久化字典树+lca)的更多相关文章
- 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 - 6191 Query on A Tree (可持久化字典树/字典树合并)
题目链接 题意:有一棵树,树根为1,树上的每个结点都有一个数字x.给出Q组询问,每组询问有两个值u,x,代表询问以结点u为根的子树中的某一个数与x的最大异或值. 解法一:dfs序+可持久化字典树.看到 ...
- HDU 4557 Tree(可持久化字典树 + LCA)
http://acm.hdu.edu.cn/showproblem.php?pid=4757 题意: 给出一棵树,每个结点有一个权值,现在有多个询问,每次询问包含x,y,z三个数,求出在x到y的路径上 ...
- hdu 6191--Query on A Tree(持久化字典树)
题目链接 Problem Description Monkey A lives on a tree, he always plays on this tree. One day, monkey A l ...
- BZOJ - 2588 Spoj 10628. Count on a tree (可持久化线段树+LCA/树链剖分)
题目链接 第一种方法,dfs序上建可持久化线段树,然后询问的时候把两点之间的所有树链扒出来做差. #include<bits/stdc++.h> using namespace std; ...
- HDU.4757.Tree(可持久化Trie)
题目链接 \(Description\) 给定一棵树,点有点权.\(Q\)次询问\(x,y,z\),求\(x\)到\(y\)的简单路径中,与\(z\)异或能得到的最大的数是多少. \(Solution ...
- 【HDU 6191】Query on A Tree 【可持久化字典树】
题目 给出一棵有n个结点的树,树根是1,每个结点给出一个value.然后给出q个询问,每个询问给出两个整数u和x,你要在以u结点为根的子树中找出一个结点v,使得val[v] xor x最大, 并输出这 ...
- BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 9280 Solved: 2421 ...
随机推荐
- 根据一个经纬度坐标获取周边最近经纬。Java实现
1.需求:指定一个经纬度坐标,如:(31.2121751783,121.4411213954).周围有一堆经纬度坐标,找出与它最近的那个. 2.实现思路:将给出经纬度看成原点(0,0).周围经纬度定位 ...
- 「SCOI2016」背单词
「SCOI2016」背单词 Lweb 面对如山的英语单词,陷入了深深的沉思,「我怎么样才能快点学完,然后去玩三国杀呢?」.这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,然后 ...
- 筆記本 wifi走外网线 網卡走內網
筆記本 wifi走外网线 網卡走內網 ,案列 -------------------------------------------------------- route print ...
- MySQL timestampdiff 和 timestampadd 的用法
在应用时,经常要使用这两个函数TIMESTAMPDIFF和TIMESTAMPADD. 一,TIMESTAMPDIFF 语法: TIMESTAMPDIFF(interval,datetime_expr1 ...
- Struts1.3——使用MyEclipse集成工具开发Struts
前面两篇通过手工写代码,手工配置struts-config.xml文件的方法来开发了一个最简单的struts项目,通过手工的方式旨在学习底层原理细节.当熟悉了以后,我们就不需要再通过纯手工的方式来开发 ...
- python3_列表排序简介
说明:以下是以整数排列为例,其它数据类型读者自行思考即可知. 1.使用方法sort()对列表排序 使用格式:(注:说到方法,在列表中都是列表名.方法名()的使用格式,之后不在赘述.) 列表名.sort ...
- nginx-413
修改nginx配置文件:client_max_body_size 300M 修改php.ini upload_max_filesize | post_max_size
- IOU计算python实现
def compute_iou(rec1, rec2): """ computing IoU :param rec1: (y0, x0, y1, x1), which r ...
- 以您熟悉的编程语言为例完成一个hello/hi的简单的网络聊天程序
Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信,应用程序通常通过"套接字"向网络发出 ...
- fdisk分区实例
查看磁盘分区详情 直接使用fdisk -l 或者使用fdisk /dev/sda,再使用p命令来查看 Command (m for help): p Disk /dev/sda: 32.2 GB, 3 ...