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 ...
随机推荐
- Cowboy http服务器 websocket
一.基础介绍 cowboy是一个小巧.快速.模块化的http服务器,采用Erlang开发.其中良好的clean module使得我们可以扩展到多种网络协议之中,cowboy自带的有tcp和ssl,而也 ...
- MyLog
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;us ...
- Android四大组件之 --- Service入门
在前面了解了什么是多线程和异步消息处理机制后,我们来看一下到底什么是Service. 1. 什么是service(service的作用)一个服务是一个具有较长生命周期但没有用户界面的程序,例如:一个正 ...
- 关于org.apache.jasper.JasperException解决方法
没有导入jstl.jar包 解决办法:在项目pom.xml中添加maven项目的jstl.jar 如果导入jstl.jar包 解决办法:检查jstl.jar版本是否与项目兼容,不兼容则切换jstl.j ...
- Openresty 进行限流的方法
1.使用Openresty进行限流, 使用漏桶原理进行设计 和路由系统设计类似. LUA脚本去通过变量去redis取值,从redis中得到队列的大小.漏和桶的大小. 然后通过比较,队列大小与漏和桶进行 ...
- SqlServer 游标逐行更新数据,根据上一行的数据来更新当前行
工作中用到的记录一下,游标的详细定义及说明请百度 --游标格式化数据 DECLARE cursor_jxsmb CURSOR FOR --定义一个游标 SELECT F0 FROM dbo.JXSMB ...
- 关于第一次在IDEA上使用lombok时注解完全不起作用
当你第一次在IDEA上使用lombok这个工具包时,如果你没有在setting--->Plugins-->Marketplace-->安装Lombok plugin 同时设置 Set ...
- ajax请求,函数外无法获取请求的数据问题解决
一.开发中遇到需要通过ajax请求获取其他函数能否执行的状态,但是当赋值给statusFlag时发现无法赋值:ajax请求默认为异步的方式,该请求的操作被放置在任务队列中,并不会按顺序执行,所以被赋值 ...
- Sonar 平台搭建及 Sonar 自定义规则打包部署篇
引言 基于阿里开发手册的sonar自定义插件工程 开源地址: https://github.com/tigerge000/sonar-java-custom-rules.git由于最近来问童鞋,就算写 ...
- Python_在Ubuntu中搭建科学计算环境
本文针对 Ubuntu 下搭建 Python 科学计算的环境,罗列了关键词和部分链接,最后附上了自己的一点分享. 1.升级 关键词: python ubuntu 升级 推荐: ubuntu16.04下 ...