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

传送门

其实好几天之前就写了

结果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. 技术分享:RxJS实战练习-经典游戏Breakout

    效果图 数据流分析 1.ticker$ 数据流 interval配合scheduler/animationFrame 作为游戏随时间变化的控制数据流 ticker$ = interval(this.T ...

  2. mysql锁机制详解

    前言 大概几个月之前项目中用到事务,需要保证数据的强一致性,期间也用到了mysql的锁,但当时对mysql的锁机制只是管中窥豹,所以本文打算总结一下mysql的锁机制. 本文主要论述关于mysql锁机 ...

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

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

  4. mysql数据插入前判断是否存在

    今天在对一些抓取到的数据做插入的时候,因为使用了定时器,每间隔几分钟会抓取一次,导致很多数据插入的是重复数据,为了解决这个问题, 一般是在插入之前先通过一个标识去查询表数据看是否已经有了,没有再执行插 ...

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

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

  6. EF 的 CURD 操作

    EF 的 CURD 操作 这里采用了数据库 Northwind,下载地址:https://northwinddatabase.codeplex.com/ 增 /// <summary> / ...

  7. PHP中利用pcntl实现多进程(模拟多线程)实例(转)

    windows不支持pcntl的多线程(非Unix类系统不支持此模块),pcntl在很久很久之前就听过了,但是一直没有尝试着真正要用它. 这不,遇到socket问题了,看socket,遇到pcntl了 ...

  8. 浅谈"n个球"和"m个盒子"之间的乱伦关系

    无视标题,从我做起 update in 2018.10.1: 补充了"至多为1的四中情况" 这玩意儿的官方名字应该是叫"Twelvefold way",共用12 ...

  9. docker 学习资料收集

    Docker中文网 http://www.docker.org.cn/book/ docker镜像怎么迁移到其他的服务器 http://www.talkwithtrend.com/Question/1 ...

  10. Android ScrollView和ListView滑动冲突解决记录

    private int mLastX; private int mLastY; public View.OnTouchListener onTouchListener = new View.OnTou ...