RMQ问题与LCA问题

一、区间最小/ 最大查询(Range Minimum/Maximum Query) :RMQ 问题

//Toj: 2762

[ 描述] 已知长度为L 的数列A ,询问区间[l, r] 中的最值。

若询问的次数较少,可以用线性的复杂度来查询,但如果询问的次数过多且L 过大,那么复杂度就会很高。所以需要更快速的查找方法。

ST 算法:预处理O(nlogn) ,查询指定区间的最值O(1)

    把待求区间[l, r] 分为两段长为len 的区间,左边一段为[l, l+len-1] ,右边一段为[r-len+1, r] ,len 必须使得两段区间覆盖待求区间。

    设所求数组为W :

    那么,所求最小值就是两个区间的最小值的最小值:

即Min(Min{W[i], l<=i<=l+len-1}, Min{W[j], r-len+1<=j<=r})

若都在预先处理中先求得两个区间的最小值,则每次查询的复杂度都是O(1) 。

预处理:(DP )

    设dp[i][j] 表示从第i 个数起连续2^j 个数中的最值。

    dp[i][0]=a[i] 1<=i<=N

    dp[i][j]=Min(dp[i][j-1], dp[i+2^(j-i)][j-1])

求最值:把区间[l, r] 分成两个长度为2^n 的区间。

    为使区间被分解后,长度为2^n ,区间部分可重叠,但不可越过[l, r] 。

    例如 [3, 9] à [3, 6]+[6, 9] 即:dp[3, 2] 和dp[6, 2]

注:Dmin 与Dmax 用前清零。

 

将RMQ 拓展到二维状况时,依然使用ST 算法先进行预处理,再进行查询。其中可以有两种做法(以取最大值为例),对于数字矩阵num[1..M][1..N] ,取其中一个子矩阵的最大值。第一种方法:Dmax[x][y][i][j] 表示对于点(x, y) 为左上点,(x+2^i-1, y+2^j-1) 为右下点的子矩阵的最大值。在询问时,将待查询矩阵一分为四取最大值即可。

//Toj: 3375

第二种方法:是Dmax[x][y][i] 记录以(x, y) 为左上点,(x+2^i-1, y+2^i-1) 为右下点的正子矩阵的最大值。在询问时,也需要将待查询矩阵分为若干正子矩阵,取最大值即可。

第二种方法由于比第一种方法在Dmax 上少了一个维度,所以大大的节省了空间。

一、 最近公共祖先( Lowest Common Ancestors ) :LCA 问题

//Toj: 3361 1051

    对于有根树T 的两个结点u 、v ,最近公共祖先LCA(T, u, v) 表示一个结点x ,满足x 是u 、v 的祖先且x 的深度尽可能大。另一种理解方式是把T 理解为一个无向无环图,而LCA(T, u, v) 即u 到v 的最短路上深度最小的点。

    解决LCA 主要是用最经典的Tarjan 离线算法,需要用到并查集来辅助。

1 、在并查集中建立仅包含x 结点的集合,即Fa[x]=x;

2 、处理x 的所有孩子,处理完每个孩子后,令Fa[ 孩子]=x ,即将孩子和x 所在集合合并;

3 、全部孩子处理完后,将x 标记为处理结束;

4 、处理所有与x 相关的询问。对于每个询问LCA(x, y) ,若y 已被标记,则记录下LCA(x, y)=Find(y) ,即y 所在集合的代表元素。

[ 模板] ( 以3361 为例)

在处理询问的时候需要建立关联序列表,另外调用LCA 时候必须调用根结点。

在查询的时候根据题意修改。

二、 LCA 与RMQ :

// 资料:RMQ 与LCA 问题( 郭华阳).ppt

RMQ 向LCA 转化:设序列A 的长度为N

    1 、设序列中最小值为为Ak ,建立优先级为Ak 的根结点Tk ;

    2 、将A[1..k-1] 递归建树作为Tk 的左子树;

3 、将A[k+1..N] 递归建树作为Tk 的右子树。

RMQ(A, i, j) 查询A[i..j] 的最值即为LCA(T, i, j) 。

LCA 向RMQ 转化:

    对有根树T 进行DFS ,将遍历到的结点按照顺序记下,得到一个长度为2*N-1 的序列,称之为T 的欧拉序列F ,每个结点在欧拉序列中出现,记录pos[u] 为结点u 在欧拉序列中

第一次出现的位置。

    LCA(T, u, v)=RMQ(B, pos(u), pos(v))

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值