Intro to LCA & RMQ

buaa prime21

LCA&RMQ

在有根树下定义如下概念:

祖先:从该节点到根节点的路径上的所有节点(除该点外)称之为其祖先。

深度:从此节点到根节点的距离+1

最近公共祖先(LCA):对于两个点u,v的所有公共祖先中,深度最深的那一个。记作LCA(T,u,v)

RMQ(区间最值查询)问题:对于一个长度为n的数列A,询问RMQ(A,i,j),返回Ai~Aj中所有数的最大/小值

我们常常把这两个算法相提并论是因为其可以互相转化

栗子

1

2

3

4

5

6

7

如左,在树T中,1为根

LCA(T,7,5)=2,LCA(T,7,3)=1,LCA(T,2,7)=2

\{ a_n \} = {3,5,1,2,7,4,6}
{an}=3,5,1,2,7,4,6\{ a_n \} = {3,5,1,2,7,4,6}

如左

RMQ(A,1,1)=3,RMQ(A,2,6)=7,RMQ(A,3,4)=2

一些规定

离线问题:已知所有的询问,再依次作出回答

在线问题:对于每次询问,必须作出本次回答,才能得到下次询问

对于一个在线算法,设预处理的时间复杂度为O(f(n)),每次询问的时间复杂度O(g(n))

则我们记算法的复杂度为O(f(n))-O(g(n))

在这里我们暂且把并查集路径压缩的复杂度当作O(n)

LCA问题的离线解决方法--tarjan算法

query Q[N];// Q[u]中存下所有形如LCA(u,*)的询问

void LCA(node u){
    make_set(u);
    ans[find_set(u)]=u;
    for (v:u的所有儿子)
    {
        LCA(v);
        union(u,v);
        ans[find_set(u)]=u;
    }
    vis[u]=true;
    for (v: Q[u]中所有询问的另一个点)
    if (vis[v])
        get_ans[query_id(u,v)]=ans[find_set(v)];
}

make_set(u):

为u节点建立一个新集合

find_set(u):

找出u所在集合的标号

union(u,v):

将u,v所在的集合求并

query_id(v,u):

得到LCA(u,v)是第几个询问

时间复杂度分析:每一个点被访问一次,每一个询问被访问两次,其他为并查集操作。故复杂度为O(N+Q)

倍增思想解决LCA&RMQ

ST算法:

d[i,j]=max\{a_i,...,a_{i+2^j-1}\}
d[i,j]=max{ai,...,ai+2j1}d[i,j]=max\{a_i,...,a_{i+2^j-1}\}
d[i,j]=max\{d[i,j-1],d[i+2^{j-1},j-1]\}
d[i,j]=max{d[i,j1],d[i+2j1,j1]}d[i,j]=max\{d[i,j-1],d[i+2^{j-1},j-1]\}
q[i,j]=max\{a_i,...,a_j\} \quad L=\lfloor \log_2 (j-i+1) \rfloor
q[i,j]=max{ai,...,aj}L=log2(ji+1)q[i,j]=max\{a_i,...,a_j\} \quad L=\lfloor \log_2 (j-i+1) \rfloor
q[i,j]=max\{d[i][L],d[j-2^L+1][L]\}
q[i,j]=max{d[i][L],d[j2L+1][L]}q[i,j]=max\{d[i][L],d[j-2^L+1][L]\}

对于RMQ:O(NlogN)-O(1)

对于LCA:O(NlogN)-O(logN)

fa[u][k]=fa[fa[u][k-1]] \quad fa[u][0]=u \quad f[u][i]=fa[u][2^i]
fa[u][k]=fa[fa[u][k1]]fa[u][0]=uf[u][i]=fa[u][2i]fa[u][k]=fa[fa[u][k-1]] \quad fa[u][0]=u \quad f[u][i]=fa[u][2^i]
int get(int u,int v){
    if (deep[u]>deep[v]) swap(u,v);
    u=fa[u][deep[u]-deep[v]];
    if (u==v) return u;
    for (int i=max_log_deep;i>=0;i--)
    if (f[u][i]!=f[v][i])
    {
        u=f[u][i];
        v=f[v][i];
    }
    return f[u][0];
}

LCA与RMQ问题的互相转化

LCA转RMQ

1

2

3

4

5

6

7

对树进行dfs,记录树的欧拉序,设R[u]为u节点第一次出现在欧拉序中的序号,设D[i]为欧拉序中第i个节点的深度,则:

LCA(T,u,v)=R[RMQ_id(D,R[u],R[v])]

LCA与RMQ问题的互相转化

RMQ转LCA

\{ a_n \} = {3,5,1,2,7,4,6}
{an}=3,5,1,2,7,4,6\{ a_n \} = {3,5,1,2,7,4,6}

一个数列所对应的笛卡尔树具有如下性质:

1.是一颗二叉树

2.中序遍历恰为原数列

3.每一个点恰好是其子树中的最小/最大值

一种O(n)构造笛卡尔树的方法:

用一个单调栈存储当前笛卡尔树的最右链,用如下方法加入一个点:

1.若满足单调栈的单调性,若栈非空作为栈顶的右孩子,压入单调栈

2.若不满足,不断弹出栈顶元素,直到空栈或满足单调性,进行操作1,只后将最后一次弹出的元素作为该点的左孩子

理性愉悦时间

±1RMQ问题

若对一个具有如下性质的数列做RMQ问题,我们记作±1RMQ问题

\forall x \in \{ x | 1 \leq x < n \} , | A_x-A_{x+1} |=1
x{x1x<n},AxAx+1=1\forall x \in \{ x | 1 \leq x < n \} , | A_x-A_{x+1} |=1

对于±1RMQ问题问题,我们存在一个O(n)-O(1)的在线算法

注意定理:对于数列A[i]-B[i]=C(为常数),则A、B两数列最小值在同一处。

由定理易知,长度为n的本质不同的具有此性质的数列是O(2^n)级别的

理性愉悦时间

±1RMQ问题—预处理算法

1.将数列分成n/k块,每一块大小为k,用O(n)的时间求得第i块的最小值A*[i]

2.对A*数列做ST算法的预处理:O(n/k log n/k)

3.由于长度为k的数列仅有2^k种,对这2^k种数列求出所有可能的n^2种询问的回答:O(2^k*k*k),记RMQ_in(kd,x,y)表示第kd种数列从x到y的RMQ值

对于2,3,要使得复杂度为O(n)级别,可取

k=\lfloor \frac{ \log_2 n }{2} \rfloor
k=log2n2k=\lfloor \frac{ \log_2 n }{2} \rfloor

理性愉悦时间

±1RMQ问题—询问算法

设l,r所在的块分别为x,y,记x,y两块所属的种类分别为kx,ky,l,r在块中的位置为a,b,分两种情况讨论:

RMQ(A,l,r)=RMQ\_in(kd,a,b)
RMQ(A,l,r)=RMQ_in(kd,a,b)RMQ(A,l,r)=RMQ\_in(kd,a,b)
2. \ x \neq y
2. xy2. \ x \neq y
1. \ x = y
1. x=y1. \ x = y
RMQ(A,l,r)=\max \begin{cases} RMQ\_in(kx,a,k) \\ RMQ(A^*,kx+1,ky-1) \\ RMQ\_in(ky,1,b) \end{cases}
RMQ(A,l,r)=max{RMQ_in(kx,a,k)RMQ(A,kx+1,ky1)RMQ_in(ky,1,b)RMQ(A,l,r)=\max \begin{cases} RMQ\_in(kx,a,k) \\ RMQ(A^*,kx+1,ky-1) \\ RMQ\_in(ky,1,b) \end{cases}

可以发现之前之前LCA转化为的RMQ问题恰为一个±1RMQ问题

至此所有问题得到解决

若要实现LCA和RMQ的在线O(n)-O(1)算法按照此途径:

LCA->±1RMQ

RMQ->LCA->±1RMQ

RMQ的另一种在线做法

Segment tree: O(N)-(logN)

LCA的另一种在线做法

High Light Decomposition:O(N)-O(logN)

Easy

给出一个非降序排列的整数数组an,对于一系列询问(i,j),回答ai~aj种出现次数最多的值所出现的次数

hint:游程编码

Easy

NOIP 2013 货车运输

A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

hint 最大瓶颈生成树 = MST

Summary

  1. 了解LCA和RMQ直接的互相转化
  2. 熟练掌握tarjan算法,ST算法
  3. 熟练掌握其他RMQ,LCA
  4. 了解±1RMQ问题,LCA和RMQ的理论高效做法
  5. LCA和RMQ的简单应用

Intro to LCA & RMQ

By prime21

Intro to LCA & RMQ

  • 807