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

传送门

其实好几天之前就写了

结果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. 自己构建一个Spring自定义标签以及原理讲解

    平时不论是在Spring配置文件中引入其他中间件(比如dubbo),还是使用切面时,都会用到自定义标签.那么配置文件中的自定义标签是如何发挥作用的,或者说程序是如何通过你添加的自定义标签实现相应的功能 ...

  2. SmartSql 更新日志

    SmartSql 更新历史记录 3.7.0 support cross SqlMap reference for #30 modifying Statement.Ref for delay depen ...

  3. [整理+原创]ubuntu Thunderbird Mail设置自动提醒

    开机启动的设置方法 // 在终端输入 gnome-session-properties 然后添加thunderbird为启动项 方法1——自动提醒 下载插件:Thunderbird Mail客户端菜单 ...

  4. 5分钟入门git模式开发

    本文由云+社区发表 作者:唐维黎 导语 基于gui工具TortoiseGit让你快速进入git开发模式. 目前项目已逐步从svn移步到git开发模式,其中也针对git统一协议了适合git的开发规范, ...

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

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

  6. Python四步实现决策树ID3算法,参考机器学习实战

    一.编写计算历史数据的经验熵函数 from math import log def calcShannonEnt(dataSet): numEntries = len(dataSet) labelCo ...

  7. Spring Cloud Alibaba基础教程:支持的几种服务消费方式(RestTemplate、WebClient、Feign)

    通过<Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现>一文的学习,我们已经学会如何使用Nacos来实现服务的注册与发现,同时也介绍如何通过LoadBal ...

  8. [JavaScript] audio在浏览器中自动播放

    audio 在浏览器中自动播放 autoplay 属性 autoplay 属性规定一旦音频就绪马上开始播放. 如果设置了该属性,音频将自动播放. 使用 autoplay 属性进行播放 //使用auto ...

  9. JAVA Swing 改变标题栏左上角默认咖啡图标

    前言 最近使用Java的swing开发了一个小程序,想要实现改变标题栏左上角的图标,找了网上的资料,经过了一个下午的尝试,都是未能成功,最后,终于是在Java的一本书上找到了结果 我只能说,网上的东西 ...

  10. 零基础学Python--------入门篇 第1章 初始Python

    入门篇 第1章  初始Python 1.1  Pyhton 概述 1.1.1 了解 Python Python,本义是指“蟒蛇”.1989年,荷兰人Guido van Rossum发明了一种面向对象的 ...