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
如左
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算法:
对于RMQ:O(NlogN)-O(1)
对于LCA:O(NlogN)-O(logN)
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
一个数列所对应的笛卡尔树具有如下性质:
1.是一颗二叉树
2.中序遍历恰为原数列
3.每一个点恰好是其子树中的最小/最大值
一种O(n)构造笛卡尔树的方法:
用一个单调栈存储当前笛卡尔树的最右链,用如下方法加入一个点:
1.若满足单调栈的单调性,若栈非空作为栈顶的右孩子,压入单调栈
2.若不满足,不断弹出栈顶元素,直到空栈或满足单调性,进行操作1,只后将最后一次弹出的元素作为该点的左孩子
理性愉悦时间
±1RMQ问题
若对一个具有如下性质的数列做RMQ问题,我们记作±1RMQ问题
对于±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)级别,可取
理性愉悦时间
±1RMQ问题—询问算法
设l,r所在的块分别为x,y,记x,y两块所属的种类分别为kx,ky,l,r在块中的位置为a,b,分两种情况讨论:
可以发现之前之前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