题目hdu5266

分析:多节点的LCA就是dfs序中最大最小两个节点的LCA。所以只要每次维持给出节点的dfs序的最大最小,然后就是两点的LCA

代码:

rmq的st+lca的倍增

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
const int max_=;
int n;
int edge[max_*];
bool vis[max_];
int deep[max_];
int p[max_][];
int dp_min[max_][];
int dp_max[max_][];
int a[max_];
//int smax[max_][25],smin[max_][23];
int tot,idx;
void init()
{
tot=;
memset(edge,-,sizeof(edge));
idx=;
memset(vis,,sizeof(vis));
memset(deep,,sizeof(deep));
memset(p,-,sizeof(p));
}
struct tree{
int to;
int next;
}G[max_*]; void add_edge(int u,int v)
{
G[++tot].to=v;
G[tot].next=edge[u];
edge[u]=tot;
}
void dfs(int u)
{
vis[u]=;
a[u-]=idx++;
for(int i=edge[u];~i;i=G[i].next)
{
int v=G[i].to;
if(!vis[v])
{
p[v][]=u;
deep[v]=deep[u]+;
dfs(v);
}
}
}
int Max(int x,int y)
{
if(a[x]>a[y])
return x;
else
return y;
}
int Min(int x,int y)
{
if(a[x]>a[y])
return y;
else
return x;
}
void st_init()
{
for(int i=;i<n;i++)
{
dp_max[i][]=i,
dp_min[i][]=i;
}
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<n;i++)
{
dp_max[i][j]=Max(dp_max[i][j-],dp_max[i+(<<(j-))][j-]);
dp_min[i][j]=Min(dp_min[i][j-],dp_min[i+(<<(j-))][j-]);
}
}
int st_q_max(int l,int r)
{
int k=;
while((<<(k+))<=r-l+)
k++;
return Max(dp_max[l][k],dp_max[r-(<<k)+][k]);
}
int st_q_min(int l,int r)
{
int k=;
while((<<(k+))<=r-l+)
k++;
return Min(dp_min[l][k],dp_min[r-(<<k)+][k]);
}
void lca_init()
{
for(int j=;(<<j)<=n;j++)
for(int i=;i<=n;i++)
if(~p[i][j-])
p[i][j]=p[p[i][j-]][j-];
}
int lca(int u,int v)
{
if(deep[u]<deep[v])//u_max;
swap(u,v);
int k=deep[u]-deep[v];
for(int i=;(<<i)<=k;i++)
{
if((<<i)&k)
u=p[u][i];
}
if(u==v)
return u;
int N=log2((double)n);
for(int i=N;i>=;i--)
{
if(p[u][i]!=p[v][i])
{
u=p[u][i],
v=p[v][i];
}
}
return p[u][];
}
int main()
{
while(~scanf("%d",&n)){
init();
int u,v;
for(int i=;i<n;i++)
{
scanf("%d %d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs();
st_init();
int Q;
scanf("%d",&Q);
lca_init();
while(Q--)
{
int l,r;
scanf("%d %d",&l,&r);
l--,r--;
int id_max=st_q_max(l,r)+;
int id_min=st_q_min(l,r)+;
printf("%d\n",lca(id_max,id_min));
}
}
}

区间节点的lca的更多相关文章

  1. 面试题6:二叉树最近公共节点(LCA)《leetcode236》

    Lowest Common Ancestor of a Binary Tree(二叉树的最近公共父亲节点) Given a binary tree, find the lowest common an ...

  2. 区间最深LCA

    求编号在区间[l, r]之间的两两lca的深度最大值. 例题. 解:口胡几种做法.前两种基于莫队,第三种是启发式合并 + 扫描线,第四种是lct + 线段树. ①: 有个结论就是这个答案一定是点集中D ...

  3. [hdu5266]区间LCA

    题意:给一棵树,求节点L,L+1,...R的最近公共祖先 思路:先对树dfs一下,从根1出发,经过每条边时记录一下终点和到达这个点的时间截,令r[u]表示到达u这个节点的最早时间截,t[x]表示在时间 ...

  4. LCA + 树状数组 + 树上RMQ

    题目链接:http://poj.org/problem?id=2763 思路:首先求出树上dfs序列,并且标记树上每个节点开始遍历以及最后回溯遍历到的时间戳,由于需要修改树上的某两个节点之间的权值,如 ...

  5. 浅谈 LCA

    LCA问题 一.概述: 在图论与计算科学中,两个节点 v 与 w 在有向无环图( directed acyclic graph , DAG )或树中的最近公共祖先(Lowest common ancc ...

  6. 【算法】RMQ LCA 讲课杂记

    4月4日,应学弟要求去了次学校给小同学们讲了一堂课,其实讲的挺内容挺杂的,但是目的是引出LCA算法. 现在整理一下当天讲课的主要内容: 开始并没有直接引出LCA问题,而是讲了RMQ(Range Min ...

  7. LCA算法解析-Tarjan&倍增&RMQ

    原文链接http://www.cnblogs.com/zhouzhendong/p/7256007.html UPD(2018-5-13) : 细节修改以及使用了Latex代码,公式更加美观.改的过程 ...

  8. LCA转换成RMQ

    LCA(Lowest Common Ancestor 最近公共祖先)定义如下:在一棵树中两个节点的LCA为这两个节点所有的公共祖先中深度最大的节点. 比如这棵树 结点5和6的LCA是2,12和7的LC ...

  9. 求 LCA 的三种方法

    (YYL: LCA 有三种求法, 你们都知道么?) (众神犇: 这哪里来的傻叉...) 1. 树上倍增 对于求 LCA, 最朴素的方法是"让两个点一起往上爬, 直到相遇", &qu ...

随机推荐

  1. 阿里云服务器安装mongodb

    1.下载mongodb curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.9.tgz 2.解压 tar zxvf mo ...

  2. java.net.ProtocolException: Exceeded stated content-length of: '13824' bytes

    转自:https://blog.csdn.net/z69183787/article/details/18967927 1. 原因: 因为weblogic会向response中写东西造成的,解决方式是 ...

  3. ansible笔记(三)--模块讲解

    ansible 常用命令 ansible-doc ansible-playbook ansible-vault ansible-console ansible-galaxy ansible-pull ...

  4. 人生苦短_我用Python_logging日志操作_011

    话不多说,开搞,基础是先使用自带loggin模块,level为warning以上, 进一步是自定义logger,level可自定义 #!/usr/bin/env python # -*- coding ...

  5. max_length 属性

    错误:漏掉了 max_length  属性 ERRORS:users.UserProfile.image: (fields.E210) Cannot use ImageField because Pi ...

  6. C++ 彩色图像(RGB)三通道直方图计算和绘制,图像逆时针旋转90° 实现代码

    #include "iostream" #include "opencv2/opencv.hpp" #include "vector" us ...

  7. Android自动化测试框架UIAutomator原理浅析

    UIAutomator是一个Android自动化测试框架,是谷歌在Android4.1版本发布时推出的一款用Java编写的UI测试框架,它只能用于UI即黑盒方面的测试.所以UIAutomator只能运 ...

  8. 每天一个linux命令:head(15)

    head head命令用于显示文件的开头的内容.在默认情况下,head命令显示文件的头10行内容. 格式 head [参数] [文件] ​ 参数选项 参数 备注 -q 不显示文件名的头信息 -v 总是 ...

  9. LYOI2016 Summer 一次函数 (线段树)

    题目描述 fqk 退役后开始补习文化课啦,于是他打开了数学必修一开始复习函数,他回想起了一次函数都是 f(x)=kx+b的形式,现在他给了你n个一次函数 fi(x)=kix+b,然后将给你m个操作,操 ...

  10. 【Linux】grep显示匹配行的上下几行的用法

    打印匹配行的前后5行 grep -5 ‘something’ file 打印匹配行的前后5行 grep -C 5 ‘something’ file 打印匹配行的后5行 grep -A 5 ‘somet ...