区间节点的lca
分析:多节点的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的更多相关文章
- 面试题6:二叉树最近公共节点(LCA)《leetcode236》
Lowest Common Ancestor of a Binary Tree(二叉树的最近公共父亲节点) Given a binary tree, find the lowest common an ...
- 区间最深LCA
求编号在区间[l, r]之间的两两lca的深度最大值. 例题. 解:口胡几种做法.前两种基于莫队,第三种是启发式合并 + 扫描线,第四种是lct + 线段树. ①: 有个结论就是这个答案一定是点集中D ...
- [hdu5266]区间LCA
题意:给一棵树,求节点L,L+1,...R的最近公共祖先 思路:先对树dfs一下,从根1出发,经过每条边时记录一下终点和到达这个点的时间截,令r[u]表示到达u这个节点的最早时间截,t[x]表示在时间 ...
- LCA + 树状数组 + 树上RMQ
题目链接:http://poj.org/problem?id=2763 思路:首先求出树上dfs序列,并且标记树上每个节点开始遍历以及最后回溯遍历到的时间戳,由于需要修改树上的某两个节点之间的权值,如 ...
- 浅谈 LCA
LCA问题 一.概述: 在图论与计算科学中,两个节点 v 与 w 在有向无环图( directed acyclic graph , DAG )或树中的最近公共祖先(Lowest common ancc ...
- 【算法】RMQ LCA 讲课杂记
4月4日,应学弟要求去了次学校给小同学们讲了一堂课,其实讲的挺内容挺杂的,但是目的是引出LCA算法. 现在整理一下当天讲课的主要内容: 开始并没有直接引出LCA问题,而是讲了RMQ(Range Min ...
- LCA算法解析-Tarjan&倍增&RMQ
原文链接http://www.cnblogs.com/zhouzhendong/p/7256007.html UPD(2018-5-13) : 细节修改以及使用了Latex代码,公式更加美观.改的过程 ...
- LCA转换成RMQ
LCA(Lowest Common Ancestor 最近公共祖先)定义如下:在一棵树中两个节点的LCA为这两个节点所有的公共祖先中深度最大的节点. 比如这棵树 结点5和6的LCA是2,12和7的LC ...
- 求 LCA 的三种方法
(YYL: LCA 有三种求法, 你们都知道么?) (众神犇: 这哪里来的傻叉...) 1. 树上倍增 对于求 LCA, 最朴素的方法是"让两个点一起往上爬, 直到相遇", &qu ...
随机推荐
- 对VS2019进行32位汇编环境配置
1.库文件(很重要) 用我这一份就行:https://www.lanzous.com/i6364hg 2.VS依赖库 打开VS2019,选择桌面向导 配置项目时,选择新项目. 选择生成依赖项 选中ma ...
- Git相关命令整理
git config --global user.name //配置姓名git config --global user.email //配置邮箱git config --list //查看配置 ...
- Redis在windows下的环境搭建
Redis在windows下的环境搭建 下载windows版本redis,,官方下载地址:http://redis.io/download, 不过官方没有Windows版本,官网只提供linux版本的 ...
- loj2542 「PKUWC2018」随机游走 MinMax 容斥+树上高斯消元+状压 DP
题目传送门 https://loj.ac/problem/2542 题解 肯定一眼 MinMax 容斥吧. 然后问题就转化为,给定一个集合 \(S\),问期望情况下多少步可以走到 \(S\) 中的点. ...
- Web前端性能优化详解之CSS与JS加载
浏览器加载页面和渲染过程 加载过程 浏览器根据DNS 服务器得到域名的IP地坛 向这个 IP 的机器发送 HTTP请求 服务器收到,处理并返回 HTTP请求 浏览器得到返回内容 渲染过程 根据 HTM ...
- python基础:10.多线程装饰器模式下的单例模式
with def __enter__ def __close__ 闭包: 装饰器: 闭包的延迟绑定: 单例模式的应用:
- pythonerror ValueError:invalid literal for int() with base 10: '3.14'
解释:对于int()来说,文本输入‘3.14’这个输入是无效的,原因是int类要求输入数字或者整数字符 解决:a= int(float(value)) 注:int本身是一个类,所以返回的是int类,i ...
- find按照文件大小查找
例如,find -size +1M:查找大于 1 MB 的文件.其他参数: b: 512-byte blocks. This is the default if no unit is specifie ...
- postman-Runner
postman Runner配置 preview查看参数
- Java反射学习-2 - 获取Class对象的三种方式
package cn.tx.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import ...