回顾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的更多相关文章

  1. 倍增小结 ST 与 LCA

    倍增 倍增我是真滴不会 倍增法(英语:binary lifting),顾名思义就是翻倍. 能够使线性的处理转化为对数级的处理,大大地优化时间复杂度. (ps:上次学倍增LCA,没学会,老老实实为了严格 ...

  2. Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]

    题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...

  3. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  4. 洛谷P3703 [SDOI2017]树点涂色(LCT,dfn序,线段树,倍增LCA)

    洛谷题目传送门 闲话 这是所有LCT题目中的一个异类. 之所以认为是LCT题目,是因为本题思路的瓶颈就在于如何去维护同颜色的点的集合. 只不过做着做着,感觉后来的思路(dfn序,线段树,LCA)似乎要 ...

  5. 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  6. 倍增LCA学习笔记

    前言 ​ "倍增",作为一种二进制拆分思想,广泛用于各中算法,如\(ST\)表,求解\(LCA\)等等...今天,我们仅讨论用该思想来求解树上两个节点的\(LCA\)(最近公共祖先 ...

  7. [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)

    4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2131  Solved: 865[Submit][Statu ...

  8. [板子]倍增LCA

    倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...

  9. 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]

    题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his b ...

随机推荐

  1. TP自动提取关键词

    protected function _before_insert(&$data, $option) {        $data['create_time'] = time();       ...

  2. java的main函数组成

    package test;/*public static void main(String[] args)主函数特殊之处:1.格式是固定的2.被jvm(虚拟机)所识别和调用 public:因为权限必须 ...

  3. 简单的ALV示例

    在这里也推荐一条链接,很适合初学者:https://blog.csdn.net/Kang_xiong/article/details/64922576 这是一个特别基础的示例,适合没有任何ABAP基础 ...

  4. Python Day2 Learning record

    一.python初始化模块                                                        Python的强大之处在于他有非常丰富和强大的标准库和第三方库 ...

  5. shell脚本登录数据库

    #!/bin/bashHOSTNAME="localhost" #数据库信息 PORT="3306" USERNAME="root" PAS ...

  6. jmeter测试计划元素执行顺序

    jmeter测试计划元素执行顺序 测试计划的元素是有序的,通过以下方式执行: 1–配置节点 2–前置处理器 3–定时器 4–取样器 5–后置处理器(只在有结果可用情况下执行) 6–断言(只在有结果可用 ...

  7. 【转载】linux top命令查看内存及多核CPU的使用讲述

    转载 https://www.cnblogs.com/dragonsuc/p/5512797.html 查看多核CPU命令 mpstat -P ALL  和  sar -P ALL 说明:sar -P ...

  8. IP通信基础课堂笔记----以太网VLAN

    1.以太网与802.3格式差异 2.以太网MAC地址特点 3.以太网MAC帧字节范围:64-1518 4.协议CSMA:载波侦听多路访问 5.碰撞检测 6.网卡(适配器)

  9. swoole架构分析

    swoole的进程/线程结构 结构图如下: swoole主要由Master进程(主进程)和Manager进程配合使用完成其功能. Master进程 是一个多线程的程序.其中有一组很重要的线程,称之为R ...

  10. Jira7.10.1在Windows环境下的安装和配置

    jira安装的环境准备   1.   jira7.10的运行是依赖java环境的,也就是说需要安装jdk并且要是1.8以上版本: Java -version   2.  还需要为jira创建对应的数据 ...