ST&倍增LCA
回顾st算法,它的一大功能是求区间最值。先将整个区间划分成若干个小的区间,求出最值,然后将小的区间合并成一个大的区间,我们这里要用到一个数组minn[i][j],划重点!如果我们要求的是区间最小值,minn[i][j]代表的是从i开始往后2^j个数,这一个小区间的最小值。那么最开始minn[i][0]就是第i个数自己,那么涉及算法的主体部分来了,当我们将这若干个minn[i][0]合并成一个大的区间时,这个大区间的范围就是前一个范围的两倍(因为倍增后两个等大的小区间合成一个大区间),即
minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1])
void rmq()
{
for(int i=;i<=n;i++)
minn[i][]=a[i];
for(int j=;<<j<=n;j++)
for(int i=;i+(<<j)-<=n;i++)//为什么要减一 可以画图试试
minn[i][j]=min(minn[i][j-],minn[i+(<<(j-))][j-]);
}
预处理完了之后便是对每个询问的查询,关于查询,假设我们要查询的区间为[l,r],那么区间长度就是r-l+1。
int query(int l,int r)
{
int k=;
while(<<(k+)<=r-l+)//找到最大的子区间
k++;
return min(minn[l][k],minn[r-(<<k)+][k]);//区间重叠的情况
}
假如2*k大于r-l+1,我们就查询l往后2^k个数和r往前2^k个数,即便中间出现重复查询的情况也是合理的,这样便不会超出r-l+1的长度
关于LCA的st算法
LCA问题大体是求最近公共祖先,顾名思义,给定一棵树,对于每个询问,求出询问的两个节点的最近公共祖先
如图,假设我要求结点6和9的最近公共祖先,我们要做的是先从根结点开始进行深搜并记录每次深搜到的结点 即遍历顺序(包括)回溯,以及每个结点的深度,那么这棵树的遍历顺序便是
1 5 6 5 7 9 7 8 7 5 1 2 3 2 4 2 1
然后我们找6和9第一次出现的序号 分别是3和6,不难发现,我们要找的最近公共祖先就是在第三个数和第六个数之间,剩下的只需要判断在第三和第六个数之间哪一个数所代表结点的深度最小即可:
遍历序号 | 3 | 4 | 5 | 6 |
代表的结点 | 6 | 5 | 7 | 9 |
深度 | 3 | 2 | 3 | 4 |
因为从一个结点遍历到另一个节点肯定会经过它们的公共祖先,且是最近公共祖先,所以只需要用st求这区间结点的最小深度,然后把这个结点输出,便是最近公共祖先
下面是dfs的过程
void dfs(int node,int cur)
{
check[node]=;
dep[node]=cur;
book[node]=++sum;
dfn[sum]=node;
int i=frst[node];
while(i!=-)
{
if(!check[v[i]])
{
dfs(v[i],cur+);
dfn[++sum]=node;
}
i=nst[i];
}
}
//cur代表当前结点的深度,sum代表的是当前结点的遍历序号,这里用链式前向星存图
ST&倍增LCA的更多相关文章
- 倍增小结 ST 与 LCA
倍增 倍增我是真滴不会 倍增法(英语:binary lifting),顾名思义就是翻倍. 能够使线性的处理转化为对数级的处理,大大地优化时间复杂度. (ps:上次学倍增LCA,没学会,老老实实为了严格 ...
- Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]
题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- 洛谷P3703 [SDOI2017]树点涂色(LCT,dfn序,线段树,倍增LCA)
洛谷题目传送门 闲话 这是所有LCT题目中的一个异类. 之所以认为是LCT题目,是因为本题思路的瓶颈就在于如何去维护同颜色的点的集合. 只不过做着做着,感觉后来的思路(dfn序,线段树,LCA)似乎要 ...
- 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- 倍增LCA学习笔记
前言 "倍增",作为一种二进制拆分思想,广泛用于各中算法,如\(ST\)表,求解\(LCA\)等等...今天,我们仅讨论用该思想来求解树上两个节点的\(LCA\)(最近公共祖先 ...
- [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2131 Solved: 865[Submit][Statu ...
- [板子]倍增LCA
倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...
- 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
随机推荐
- ps文件解析(纯c解析代码)
参考链接:1. PS流的格式和解析总结 http://www.cnblogs.com/lihaiping/p/4181607.html 2. TS科普5 PES包解析 https://blog.cs ...
- js之 单例模式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- windows环境搭建nginx
1.下载安装nginx 2.启动nginx:点击nginx.exe文件,cmd,进入nginx根目录,执行start nginx 2.修改nginx配置文件nginx.conf 修改配置文件中serv ...
- jmeter之headers中的Content-Type.
jmeter在发送http post请求时,会把body 里的数据格式给携带上(最好携带上),一般在信息头里增加.另因一篇文章.感觉写的非常好.https://imququ.com/post/fou ...
- oracle 优化方法总结
分析和优化的基本步骤如下: 1.如果是SQL语句的写法问题,我们可以通过在不更改业务逻辑的情况下改写SQL来加以解决: 2.如果是不必要的全表扫描/排序而导致了目标SQL的性能问题,我们可以通过建立合 ...
- WebStorm Goland PyCharm 等JetBrains验证服务器
http://idea.iteblog.com/key.php http://idea.idbry.com 2017年12月08日20:05:08 http://xdouble.cn:8888/ ht ...
- Ricker wavelet 简介
本文依照参考文献简介 Ricker wavelet . 参考: [1] Frequency of the Ricker wavelet DOI: 10.1190/GEO2014-0441.1 [2] ...
- 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contai
之前一直使用的mysql5,突然换成8之后,有许多地方不一样,今天就碰到一个. 在使用sql语句创建表时,报错: 1055 - Expression #1 of ORDER BY clause is ...
- 页面商城总结(一)——HTML部分
学习编程,与君共勉. 在做过一些页面并且参考了许多商城页面后,对代码的书写和风格也有所体会,再次将我的经验分享给大家,希望大家也能够写出整洁有效的代码.本文主要是针对排版的问题进行总结,代码量较少,希 ...
- QWaiteCondition思考3
QWaitConditioin::wait() 接收一个mutex作为参数,这个mutex应该被调用线程初始化为锁定状态.在线程进入休眠状态(waite)之前,mutex会被解锁.当线程被唤醒(Wak ...