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= ...
随机推荐
- Linux mysql中文乱码问题
1.debian系统 (1)mysql 5.5版本之前 vim /etc/mysql/my.cnf 在 [client] 下面加入 default-character-set=utf8 在 [m ...
- 安装并配置hive
教程:http://www.bubuko.com/infodetail-2523113.html 安装好mysql,然后进入mysql: 创建hive用户: 给hive用户赋权: 创建hive数据库, ...
- 97 条 Linux 运维工程师常用命令总结[转]
1.ls [选项] [目录名 | 列出相关目录下的所有目录和文件 -a 列出包括.a开头的隐藏文件的所有文件 -A 通-a,但不列出"."和".." -l 列出 ...
- 使用PagerSlidingTabStrip实现顶部导航栏
使用PagerSlidingTabStrip配合ViewPager实现顶部导航栏. 效果图如下: PagerSlidingTabStrip是github上的一个开源项目,项目地址如下 ...
- vue懒加载 && 浏览器高度
当我们进入首页时,可能有很多条目需要显示,但是如果条目太多,我们全部将之显示出来就会造成性能的消耗,比如,我在第一条就找到了需要的或者我就看前面两条我就不想看后面的了,所以,这时候如果使用全部加载的方 ...
- java多态简单例子
/* 对象的多态性:动物 x = new 猫(); 函数的多态性:函数重载.重写 1.多态的体现 父类的引用指向了自己的子类对象 父类的引用也可以接收自己的对象 2.多态的前提 必须是类与类之间只有关 ...
- 九度oj题目1181:遍历链表
题目1181:遍历链表 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2600 解决:1125 题目描述: 建立一个升序链表并遍历输出. 输入: 输入的每个案例中第一行包括1个整数:n(1 ...
- FZU 2122——又见LKity——————【字符串匹配、暴力】
Problem 2122 又见LKity Accept: 407 Submit: 1413Time Limit: 1000 mSec Memory Limit : 32768 KB Pr ...
- bootstrap-fileinput参数
<link rel="stylesheet" href="css/bootstrapCSS/bootstrap.min.css"> <link ...
- MicroService