HDU 4757 Tree(可持续化字典树,lca)
题意:询问树上结点x到结点y路上上的权值异或z的最大值。
任意结点权值 ≤ 2^16,可以想到用字典树。
但是因为是询问某条路径上的字典树,将字典树可持续化,字典树上的结点保存在这条路径上的二进制数。
按照dfs序建树,结点u的字典树表示u到根结点路径上的字典树。
如果两个结点u和v,在同一条通往根结点的路径上,将会满足可减性。
因此只需要知道u、v、lca和fa[lca]四个结点的字典树就可以回答了。
/*********************************************************
* ------------------ *
* author AbyssFish *
**********************************************************/
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
#include<numeric>
#include<climits>
using namespace std; const int maxn = 1e5+;
const int maxd = ;
const int maxnds = (maxd+)*maxn; int hd[maxn], nx[maxn<<], to[maxn<<], ec;
void add_edge(int u,int v)
{
nx[ec] = hd[u];
to[ec] = v;
hd[u] = ec++;
}
void init_g(int n){ memset(hd+,0xff,n*sizeof(int)); ec = ; }
#define eachedge int i = hd[u]; ~i; i = nx[i]
#define ifvalid int v = to[i]; if(v == fa[u]) continue; struct Node
{
int ch[];
int v;
}p[maxnds];
int tot; int n,m;
int stk[maxd+]; inline int *dcmp(int x)
{
for(int i = ; i < maxd; i++){
stk[i] = x>>i&;
}
return stk;
} void build(int *o, int v)
{
int *s = dcmp(v);
for(int i = maxd-; i >= ; i--){
o = &(p[*o].ch[s[i]]);
p[++tot] = p[*o];
*o = tot;
p[*o].v++;
}
} int a[maxn];
int fa[maxn];
int root[maxn]; void dfs_build(int u,int f = )
{
p[root[u] = ++tot] = p[root[fa[u] = f]];
build(root+u,a[u]);
for(eachedge){
ifvalid
dfs_build(v,u);
} } int *c_cmp;
bool cmp_id(int i,int j){ return c_cmp[i] < c_cmp[j]; } int dep[maxn];
int path[maxn<<];
int pid[maxn];
int dfs_clk; void get_path(int u,int d)
{
dep[u] = d;
path[++dfs_clk] = u;
pid[u] = dfs_clk;
for(eachedge){
ifvalid
get_path(v,d+);
path[++dfs_clk] = u;
}
} struct SparseTable
{
int mxk[maxn<<];
int d[maxn<<][];
void init(int *mp,int *r, int n)
{
mxk[] = -;
for(int i = ; i <= n; i++){
d[i][] = r[i];
mxk[i] = ((i&(i-)) == ) ?mxk[i-]+:mxk[i-];
}
c_cmp = mp;
for(int j = ; j <= mxk[n]; j++){
int t = (<<j)-, s = <<(j-);
for(int i = ; i + t <= n; i++){
d[i][j] = min(d[i][j-],d[i+s][j-],cmp_id);
}
} }
int RMQ(int l,int r)
{
int k = mxk[r-l];
return min(d[l][k],d[r-(<<k)][k],cmp_id);
}
}rmq; void lca_init(int u)
{
dfs_clk = ;
get_path(u,);
rmq.init(dep,path,dfs_clk);
} int q_lca(int u, int v)
{
if(pid[u] > pid[v]) swap(u,v);
return rmq.RMQ(pid[u],pid[v]+);
} vector<int> Tree; int cal_ch(int d)
{
int re = ;
for(int i = ; i < (int)Tree.size(); i++){
int o = Tree[i];
re += o >= ? p[p[o].ch[d]].v : -p[p[-o].ch[d]].v;
}
return re;
} void dump(int d)
{
for(int i = ; i < (int)Tree.size(); i++){
int &o = Tree[i];
o = o >= ? p[o].ch[d] : -p[-o].ch[d];
}
} int query(int x,int y,int z)
{
int re = z&~((<<)-);
int *s = dcmp(z);
Tree.clear();
Tree.push_back(root[x]);
Tree.push_back(root[y]);
int lca = q_lca(x,y);
Tree.push_back(-root[lca]);
Tree.push_back(-root[fa[lca]]); int tmp = ;
for(int i = maxd-; i >= ; i--, tmp <<= ){
int d = s[i]^;
if(cal_ch(d)){
tmp |= ;
dump(d);
}
else dump(d^);
}
return re|(tmp>>);
} void solve()
{
for(int i = ; i <= n; i++){
scanf("%d",a+i);
}
init_g(n);
for(int i = ,u,v; i < n; i++){
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
tot = ;
dfs_build();
lca_init();
for(int i = , x, y, z; i < m; i++){
scanf("%d%d%d",&x,&y,&z);
printf("%d\n",query(x,y,z));
}
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
//p[0] = {{0,0},0}; //root[0] = 0;
while(~scanf("%d%d",&n,&m)){
solve();
}
return ;
}
HDU 4757 Tree(可持续化字典树,lca)的更多相关文章
- Hdu-4757 Tree(可持久化字典树+lca)
题目链接:点这 我的github地址:点这 Problem Description Zero and One are good friends who always have fun wi ...
- 2017广西邀请赛 Query on A Tree (可持续化字典树)
Query on A Tree 时间限制: 8 Sec 内存限制: 512 MB提交: 15 解决: 3[提交][状态][讨论版] 题目描述 Monkey A lives on a tree. H ...
- hdu 1671 Phone List 字典树
// hdu 1671 Phone List 字典树 // // 题目大意: // // 有一些电话号码的字符串长度最多是10,问是否存在字符串是其它字符串的前缀 // // // 解题思路: // ...
- HDU 4757 Tree 可持久化字典树
Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4757 Des ...
- HDU 4557 Tree(可持久化字典树 + LCA)
http://acm.hdu.edu.cn/showproblem.php?pid=4757 题意: 给出一棵树,每个结点有一个权值,现在有多个询问,每次询问包含x,y,z三个数,求出在x到y的路径上 ...
- 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, ...
- HDU 4757 Tree(可持久化Trie+Tarjan离线LCA)
Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total Su ...
- hdu 1251 统计难题 (字典树入门题)
/******************************************************* 题目: 统计难题 (hdu 1251) 链接: http://acm.hdu.edu. ...
- HDU 5536 Chip Factory 字典树
Chip Factory Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...
随机推荐
- C++ GUI Qt4编程(12)-6.1FindFileDialog
1. 主要介绍了QGridLayout, QHBoxLayout, QVBoxLayout3种布局管理器的使用方法. 2. 在linux中,继承自QDialog的对话框,没有最大化.最小化.关闭按钮, ...
- CSS媒体查询及其使用
1.什么是媒体查询 媒体查询可以让我们根据设备显示器的特性(如视口宽度.屏幕比例.设备方向:横向或纵向)为其设定CSS样式,媒体查询由媒体类型和一个或多个检测媒体特性的条件表达式组成.媒体查询中可用于 ...
- CAPL编程实现诊断刷写,车联网FOTA流程自动化测试(代码篇)
原创内容,转载请注明出处 接上篇,本文主要讲CAPL编程详细实现,软件环境CANoe 11.0 一.Simulation Setup 1.建模之前,首先创建一个.DBC文件.如果不会,可以用一个 ...
- scrapy安装和框架内容
在cdm中:直接,pip install scrapy 有可能让你升级一下pip先,就输入这个:python -m pip install --upgrade pip 当它报错的话,看看它是缺了什么, ...
- ELK 插件(一) ---- head
一, 插件介绍 01, ElasticSearch Head是什么? ElasticSearch Head是集群管理.数据可视化.增删查改.查询语句可视化工具.可以对集群进行傻瓜式操作.你可以通过插件 ...
- 现学现卖】IntelliJ+EmmyLua 开发调试Unity中Xlua
http://blog.csdn.net/u010019717/article/details/77510066?ref=myread http://blog.csdn.NET/u010019717 ...
- phpstorm一些简单配置
1.字体大小和行间距 2.设置编码:包括编辑工具编码和项目编码
- 【MSDN】 SqlServer DBCC解析
汇总学习下SqlServer的DBCC指令. DBCC:Transact-SQL 编程语言提供 DBCC 语句以作为 SQL Server 的数据库控制台命令. 数据库控制台命令语句可分为以下类别. ...
- mybatis简单示例
1.引入mybatis.jar mysql-connector-java-5.1.47.jar <dependency> <groupId>org.mybatis</gr ...
- C# 用tabcontrol实现窗体类似网页排版的显示
这里做的比较简陋,可以美化下 把form设置为非顶级控件,直接放在tabcontrol里边,然后实现tabcontrol的拖拽移除tabpage显示form以及添加tabpage mousemove的 ...