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= ...
随机推荐
- ics httpDELETE 时增加 content,length 特别需求
unit: OverbyteIcsHttpProt.pasprocedure THttpCli.SendRequest(const Method, Version: String); var Head ...
- css布局,面试时经常问的布局
左侧宽固定200,高度自适应,右侧的框宽度都自适应<style> * { margin: 0; padding: 0; } html { height: auto; } body { ma ...
- Oracle 基础系列之1.1 oracle的安装
一. 1.以下是安装Oracle的一些硬件上的条件: (1).操作系统最后是windows2000(也就是服务器版的操作系统) (2).内存最好在1G以上,当然越大越好(因为Oracle服务启动就要消 ...
- isqlplus的使用
1 再安装Oracle的机器上开启服务[命令services.msc] 2 浏览器输入下面的网址: 虚拟机[安装orcale的机器]:http://localhost:5560/isqlplus/ 本 ...
- Windows 下推荐软件
神器 Dism++ Quicker(效率工具) Bandizip 火绒安全软件 Everyting(搜索神器并支持http远程连接) Xmanager VMware Workstation IDMan ...
- nyoj 364——田忌赛马——————【贪心】
田忌赛马 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Here is a famous story in Chinese history. "That ...
- js中的encodeURIComponent()函数
encodeURIComponent() 函数可把字符串作为 URI 组件进行编码. $scope.linktotheme = function () { if ($scope.curthemeid ...
- Web站点如何防范XSS、CSRF、SQL注入攻击
XSS跨站脚本攻击 XSS跨站脚本攻击指攻击者在网页中嵌入客户端脚本(例如JavaScript),当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的,比如获取用户的Cookie,导 ...
- Android滑动删除功能
今天学习了新的功能那就是滑动删除数据.先看一下效果 我想这个效果大家都很熟悉吧.是不是在qq上看见过这个效果.俗话说好记性不如赖笔头,为了我的以后,为了跟我一样自学的小伙伴们,我把我的代码粘贴在下面. ...
- 003Linux常用命令
文件操作 01 命令 : list----列出目录信息 命令格式: ls [-选项] [目录] 选项 : -a --all 不忽略以"."开头的隐藏文件 : -d --direc ...