DAY1
RMQ
RMQ即为Range Maximun/Minimum Query,范围内的区间最大/小值查询,可用线段树,树状数组,ST表等方法解决
倍增
ST表
实现ST表算法是一种倍增的方式
如下专门介绍
快速幂
预处理出
a
,
a
2
,
a
4
,
a
8
.
.
.
a,a^2,a^4,a^8...
a,a2,a4,a8...
考虑二进制,将
a
b
a^b
ab转换成一些数的乘积
显然,若
f
[
i
]
=
a
2
i
f[i]=a^{2^i}
f[i]=a2i,则
f
[
i
]
=
f
[
i
−
1
]
∗
f
[
i
−
1
]
f[i]=f[i-1]*f[i-1]
f[i]=f[i−1]∗f[i−1]
int quick_pow(int a,int b){
int ans=1,p=a;
for(int i=b;i;i>>=1){
if(i&1) ans=ans*p%mod;
p=p*p%mod;
}
return ans;
}
LCA
LCA即Lowest Common Ancestor,树上两个节点的最近公共祖先
状态:数组an[i][j]表示节点i的第
2
j
2^j
2j级祖先,
转移:
a
n
[
i
]
[
j
]
=
=
{
a
n
[
a
n
[
i
]
[
j
−
1
]
[
j
−
1
]
j
>
0
f
a
[
i
]
j
=
0
an[i][j]==\left\{ \begin{aligned} an[an[i][j-1][j-1]&&\ j>0\\ fa[i]&&\ j=0 \end{aligned} \right.
an[i][j]=={an[an[i][j−1][j−1]fa[i] j>0 j=0
若两个节点的深度相同,可倍增;若不同,可将深度较大的点调到深度较小的点,然后同上
void dfs(int x,int fa){
an[x][0]=fa,dep[x]=dep[fa]+1;
for(int i=1;i<=size;i++) an[x][i]=an[an[x][i-1]][i-1];
for(int i=0;i<g[x].size();i++){
int y=g[x][i];
if(y==fa) continue;
dfs(y,x);
}
}
int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=0;i<=size;i++)
if((dep[x]-dep[y])&(1<<i)) x=an[x][i];
if(x==y) return x;
for(int i=size;i>=0;i--){
if(an[x][i]!=an[y][i]){
x=an[x][i];
y=an[y][i];
}
}
return an[x][0];
}
ST表(sparse table)
主要运用倍增+dp的思想
状态:设一个二维数组f,表示从i开始取
2
j
2^j
2j个数的最小值,如不足则全取。
转移:
f
[
i
]
[
j
]
=
=
{
m
i
n
(
f
[
i
]
[
j
−
1
]
,
f
[
i
+
2
j
−
1
]
[
j
−
1
]
j
>
0
且
i
+
2
j
−
1
<
=
n
f
[
i
]
[
j
−
1
]
j
>
0
且
i
+
2
j
−
1
>
n
a
[
i
]
j
=
0
f[i][j]==\left\{ \begin{aligned} min(f[i][j-1],f[i+2^{j-1}][j-1] &&\ j>0且i+2^{j-1}<=n \\ f[i][j-1]&&\ j>0且i+2^{j-1}>n\\ a[i]&&\ j=0 \end{aligned} \right.
f[i][j]==⎩⎪⎨⎪⎧min(f[i][j−1],f[i+2j−1][j−1]f[i][j−1]a[i] j>0且i+2j−1<=n j>0且i+2j−1>n j=0
j从小到大枚举推出f数组
然后对于询问(l,r),设
x
=
l
o
g
2
(
r
−
l
+
1
)
x=log_2(r-l+1)
x=log2(r−l+1)
答案为
m
i
n
(
f
[
i
]
[
x
]
,
f
[
r
−
2
x
+
1
]
[
x
]
)
min(f[i][x],f[r-2^x+1][x])
min(f[i][x],f[r−2x+1][x])
基于ST表的倍增
可以在欧拉序时将深度记录下来
任意两点节点的LCA即为两个节点所在的区间的深度的最小值
就可用ST表维护
二维ST表
就是在ST表的基础上加了一维
状态:
f
[
x
]
[
y
]
[
a
]
[
b
]
f[x][y][a][b]
f[x][y][a][b]表示在横坐标为
[
x
,
m
i
n
(
n
,
x
+
2
a
−
1
)
]
[x,min(n,x+2^a-1)]
[x,min(n,x+2a−1)],纵坐标为
[
y
,
m
i
n
(
m
,
y
+
2
b
−
1
]
[y,min(m,y+2^b-1]
[y,min(m,y+2b−1]的矩形内的最大值
转移:
f
[
x
]
[
y
]
[
a
]
[
b
]
=
=
{
m
i
n
(
f
[
x
]
[
y
]
[
a
−
1
]
[
b
]
,
f
[
x
+
2
a
−
1
]
[
y
]
[
a
−
1
]
[
b
]
)
a
>
0
且
x
+
2
a
−
1
<
=
n
f
[
x
]
[
y
]
[
a
]
[
b
−
1
]
x
+
2
(
a
−
1
)
>
n
且
a
>
0
m
i
n
(
f
[
x
]
[
y
]
[
a
]
[
b
−
1
]
,
f
[
x
]
[
y
+
2
b
−
1
]
[
a
]
[
b
−
1
]
)
b
>
0
且
y
+
2
b
−
1
<
=
n
f
[
x
]
[
y
]
[
a
−
1
]
[
b
]
y
+
2
(
b
−
1
)
>
n
且
b
>
0
v
a
l
[
x
]
[
y
]
a
=
b
且
b
=
0
f[x][y][a][b]==\left\{ \begin{aligned} min(f[x][y][a-1][b],f[x+2^{a-1}][y][a-1][b])&&\ a>0且x+2^{a-1}<=n \\ f[x][y][a][b-1]&&\ x+2^(a-1)>n且a>0\\ min(f[x][y][a][b-1],f[x][y+2^{b-1}][a][b-1])&&\ b>0且y+2^{b-1}<=n \\ f[x][y][a-1][b]&&\ y+2^(b-1)>n且b>0\\ val[x][y]&&\ a=b且b=0 \end{aligned} \right.
f[x][y][a][b]==⎩⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎧min(f[x][y][a−1][b],f[x+2a−1][y][a−1][b])f[x][y][a][b−1]min(f[x][y][a][b−1],f[x][y+2b−1][a][b−1])f[x][y][a−1][b]val[x][y] a>0且x+2a−1<=n x+2(a−1)>n且a>0 b>0且y+2b−1<=n y+2(b−1)>n且b>0 a=b且b=0
对于每组询问,设
k
x
=
l
o
g
2
(
x
r
−
x
l
+
1
)
,
k
y
=
l
o
g
2
(
y
r
−
y
l
+
1
)
kx=log_2(xr-xl+1),ky=log_2(yr-yl+1)
kx=log2(xr−xl+1),ky=log2(yr−yl+1)
则答案为:
m
a
x
(
f
[
x
l
]
[
y
l
]
[
k
x
]
[
k
y
]
,
f
[
x
r
−
2
k
x
+
1
,
f
[
x
l
]
[
y
r
−
2
k
y
+
1
]
[
k
x
]
[
k
y
]
,
f
[
x
r
−
2
k
x
+
1
]
[
y
r
−
2
k
y
+
1
]
[
k
x
]
[
k
y
]
)
max(f[xl][yl][kx][ky],f[xr-2^{kx}+1,f[xl][yr-2^{ky}+1][kx][ky],f[xr-2^{kx}+1][yr-2^{ky}+1][kx][ky])
max(f[xl][yl][kx][ky],f[xr−2kx+1,f[xl][yr−2ky+1][kx][ky],f[xr−2kx+1][yr−2ky+1][kx][ky])