还是那一道洛谷的板子题来说吧

传送门

其实好几天之前就写了

结果dr实在是太弱了

没有那么多的精力

于是就一直咕咕咕了

今天终于补上来了

LCA概念传送门

RMQ传送门

这个算法是基于RMQ和欧拉序的算法

什么是Rmq?
 
RMQ (Range Minimum/Maximum Query)问题是指:
对于长度为n的数列A,
回答若干询问RMQ(A,i,j)(i,j<=n),
返回数列A中下标在i,j里的最小(大)值,
也就是说,RMQ问题是指求区间最值的问题。
解决Rmq问题常用ST算法。
 
ST算法时间复杂度:
 预处理O(nlogn)
 单次查询O(1)
 
欧拉序?
 欧拉序是一种树的遍历顺序,其他还有dfs序,这些序具有一定的性质。
 欧拉序是树dfs过程中经过 结点的顺序。
若已1->2->4->5->6->7->3的顺序dfs树

即每经过一次结点就记录一次,

n个结点的树有2n-1个记录

基于Rmq和欧拉序的Lca算法:

预处理出树的欧拉序,预处理id,vs,depth数组

id[u]表示结点u第一次被访问时的下标,

vs[i]表示欧拉序中第i个结点的编号,

depth[i]表示欧拉序中第i个结点的深度。

假设dfs顺序1->2->4->5->3

要求Lca(u,v),例如Lca(4,5),
根据dfs的性质,在第一次访问完结点4及其子树,回溯,
再第一次访问到5的过程中,途中访问过的深度最小的结点必是Lca(4,5)
 
Rmq问题。Lca(u,v)=vs[id[u]<=i<=id[v]中depth[i]最小的i]
(假设id[u]<id[v])
 
 
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn = ;
const int maxm = ;
int head[maxn],nxt[maxm],to[maxm],cnt;
int id[maxm],vis[maxm],depth[maxm],tot;
int f[maxm][],lg[maxm]; inline int read()
{
int sum = ,p = ;
char ch = getchar();
while(ch < '' || ch > '')
{
if(ch == '-')
p = -;
ch = getchar();
}
while(ch >= '' && ch <= '')
{
(sum *= )+= ch - '';
ch = getchar();
}
return sum * p;
} void add(int x,int y)//链式前向星--加边
{
nxt[++cnt] = head[x];
to[cnt] = y;
head[x] = cnt;
return;
} void dfs(int u,int fa,int dep)
{
id[u] = ++tot;
vis[tot] = u;
depth[tot] = dep;
for(int i = head[u];i;i = nxt[i])
{
int v = to[i];
if(v == fa)
continue;
dfs(v,u,dep+);
vis[++tot] = u;
depth[tot] = dep;
}
return;
} void RMQ()
{
for(int i = ;i <= tot;i++)
lg[i] = lg[i - ] + ( << lg[i - ] == i);
for(int i = ;i <= tot;i++)
f[i][] = i;
for(int j = ;( << j) <= tot;j++)
for(int i = ;i + ( << j) - <= tot;i++)
{
int a = f[i][j-];
int b = f[i + ( << (j - ))][j - ];
if(depth[a] <= depth[b])
f[i][j] = a;
else
f[i][j] = b;
}
return;
} int st(int x,int y)
{
int r = id[x];
int l = id[y];
if(r < l)
swap(r,l);
int k = lg[r - l + ] - ;
int a = f[l][k];
int b = f[r - ( << k) + ][k];
if(depth[a] <= depth[b])
return vis[a];
else
return vis[b];
} int main()
{
int n = read(),m = read(),s = read();
int x,y;
for(int i = ;i < n;i++)
{
x = read(),y = read();
add(x,y);
add(y,x);
}
dfs(s,,);
RMQ();
for(int i = ;i <= m;i++)
{
x = read(),y = read();
printf("%d\n",st(x,y));
}
return ;
}

LCA-RMQ+欧拉序的更多相关文章

  1. hdu 2586 欧拉序+rmq 求lca

    题意:求树上任意两点的距离 先说下欧拉序 对这颗树来说 欧拉序为 ABDBEGBACFHFCA 那欧拉序有啥用 这里先说第一个作用 求lca 对于一个欧拉序列,我们要求的两个点在欧拉序中的第一个位置之 ...

  2. HDU 2586(LCA欧拉序和st表)

    什么是欧拉序,可以去这个大佬的博客(https://www.cnblogs.com/stxy-ferryman/p/7741970.html)巨详细 因为欧拉序中的两点之间,就是两点遍历的过程,所以只 ...

  3. dfs序和欧拉序

    生命不息,学习不止,昨天学了两个算法,总结一下,然而只是略懂,请路过的大佬多多谅解.   一.dfs序 1.什么是dfs序? 其实完全可以从字面意义上理解,dfs序就是指一棵树被dfs时所经过的节点的 ...

  4. P3379 【模板】最近公共祖先(LCA)(欧拉序+rmq)

    P3379 [模板]最近公共祖先(LCA) 用欧拉序$+rmq$维护的$lca$可以做到$O(nlogn)$预处理,$O(1)$查询 从这里剻个图 #include<iostream> # ...

  5. lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增

    https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...

  6. Bzoj 2286 & Luogu P2495 消耗战(LCA+虚树+欧拉序)

    题面 洛谷 Bzoj 题解 很容易想到$O(nk)$的树形$dp$吧,设$f[i]$表示处理完这$i$颗子树的最小花费,同时再设一个$mi[i]$表示$i$到根节点$1$路径上的距离最小值.于是有: ...

  7. 【BZOJ3611】[Heoi2014]大工程 欧拉序+ST表+单调栈

    [BZOJ3611][Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶 ...

  8. [BZOJ3772]精神污染 主席树上树+欧拉序

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MB Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位 ...

  9. 【BZOJ 3772】精神污染 主席树+欧拉序

    这道题的内存…………………真·精神污染……….. 这道题的思路很明了,我们就是要找每一个路径包含了多少其他路径那么就是找,有多少路径的左右端点都在这条路径上,对于每一条路径,我们随便选定一个端点作为第 ...

随机推荐

  1. Mybatis sql映射文件浅析 Mybatis简介(三)

    简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML为载体映射SQL 之前提到过,各项配置信息将Mybatis应用的整 ...

  2. web缓存策略之HTTP缓存大全

    一. web缓存总分类 数据库数据缓存 Web应用,特别是SNS类型的应用,往往关系比较复杂,数据库表繁多,如果频繁进行数据库查询,很容易导致数据库不堪重荷.为了提供查询的性能,会将查询后的数据放到内 ...

  3. ZXing 生成、读取二维码(带logo)

    前言 ZXing,一个支持在图像中解码和生成条形码(如二维码.PDF 417.EAN.UPC.Aztec.Data Matrix.Codabar)的库.ZXing(“zebra crossing”)是 ...

  4. 【转】MVC HtmlHelper用法大全

    HtmlHelper用来在视图中呈现 HTML 控件. 以下列表显示了当前可用的一些 HTML 帮助器. 本主题演示所列出的带有星号 (*) 的帮助器. ActionLink - 链接到操作方法. B ...

  5. [转]gitlab cicd (二)系列之安装git-runner rpm安装方式

    本文转自:https://blog.csdn.net/qq_21816375/article/details/84308748 本编是继gitlab cicd (一)系列之安装gitlb之后,基于安装 ...

  6. array_merge和array+的区别分析

    记得之前发现很多朋友用过array+array的方式,今天索性再聊下这样的话题:如何获取字符键名相同值不同的两个数组值集合?让我认真比较了下PHP中array_merge和array相加的区别 首先来 ...

  7. Hibernate框架笔记03表操作多对多配置

    目录 1. 数据库表与表之间的关系 1.1 一对多关系 1.2 多对多关系 1.3 一对一关系[了解] 2. Hibernate的一对多关联映射 2.1 创建一个项目,引入相关jar包 2.2. 创建 ...

  8. 深入理解 JavaScript 执行上下文和执行栈

    前言 如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制.执行上下文和执行栈是 JavaScript ...

  9. Web前端:博客美化:一、模板美化

    1.选用模板simplememory 2.写css放在 这些会覆盖掉原来的css样式 我是在网上找的css代码二次加工的 : ) /*1.针对simplememory的修改*/ #google_ad_ ...

  10. splay详解(三)

    前言 上一节我们学习了splay所能解决的基本问题,这节我来讲一下splay怎么搞区间问题 实现 splay搞区间问题非常简单,比如我们要在区间$l,r$上搞事情,那么我们首先把$l$的前驱旋转到根节 ...