前置知識
一維rmq及其拓展
對於乙個n×m
n×m的矩陣,每個格仔有乙個值,有q
q個詢問,每次詢問你乙個子矩陣中的最大值。1≤
n,m≤
500,q≤
1061
≤n,m
≤500
,q≤1
06每次花子矩陣大小的複雜度去查詢。
複雜度最壞o(q
×n×m
)o(q
×n×m
)我們用n
n棵線段樹或者樹狀陣列來維護每行區間最大值,複雜度最壞o(n
mlog
m+qn
logm
)o(n
mlog
m+qn
logm
),還是沒法過,有沒有更快的方法呢?
既然是靜態的詢問,沒有修改操作,那麼很容易聯想到rmq
rmq中的sts
t表。那麼暴力的sts
t表就是和資料結構的做法類似,預處理nn個s
tst表,每次在多個sts
t表中查詢最大值,複雜度最壞為o(n
mlog
m+qn
)o(n
mlog
m+qn
),雖然能過更多的資料,但是還是不夠。
既然查詢物件是個二維矩陣,那麼我們能不能維護乙個二維的sts
t表呢?答案顯然是肯定的。
預處理:
所以我們令st[
i][j
][k]
[l]s
t[i]
[j][
k][l
],為新的sts
t表,表示以(i,
j)(i
,j)為左上角,右下角為(i+
2k−1
,j+2
l−1)
(i+2
k−1,
j+2l
−1)的矩陣中的最大值,那麼我們可以看出預處理的複雜度會是o(n
mlog
nlog
m)o(
nmlo
gnlo
gm),所以對於詢問數交少的還是用資料結構o(n
mlog
m)o(
nmlo
gm)預處理查詢比較好。
然後我們來看,對於每個st[
i][j
][k]
[l]s
t[i]
[j][
k][l
],可以由哪些狀態更新。
我們來看這個狀態表示的矩陣,如下圖:
假設這裡左上角的點aa為(
i,j)
(i,j
),右下角點dd為(
i+2k
−1,j
+2l−
1)(i
+2k−
1,j+
2l−1
),那麼我們可以把它分成兩部分,如下圖:
那麼我們將點e
e看作(i,
j+2l
−1)(
i,j+
2l−1
),其實原來的大矩陣就可以由分成的這兩個小矩陣更新得到,轉移如下:st
[i][
j][k
][l]
=maxs
t[i]
[j][
k][l
]=max其中,max
max
裡面第乙個為上半部分矩陣,後面乙個為下半部分矩陣。
如果l=0l
=0的話,就將其豎起剖成兩部分即可,是同理的。轉移如下:st
[i][
j][k
][l]
=maxs
t[i]
[j][
k][l
]=max所以最後按照k,l
k,l從小到大更新即可。
查詢
對於乙個子矩陣,我們假設它的左上角座標為(x1
,y1)
(x1
,y1
),右下角為(x2
,y2)
(x2
,y2
),那麼可以通過預處理的二維sts
t表,將其分成四部分查詢,如下圖:
其中四個部分為圖中w1(
a,e,
f,g)
,w2(
h,b,
j,i)
,w3(
m,l,
k,c)
,w4(
o,p,
d,n)
w1(
a,e,
f,g)
,w2
(h,b
,j,i
),w3
(m,
l,k,
c),w
4(o
,p,d
,n),查詢區間是可以重合的。
其實就對應了如下四個預處理的狀態,我們令p=l
og2(
x2−x
1+1)
,q=l
og2(
y2−y
1+1)
p=lo
g2(
x2−
x1+
1),q
=log
2(y
2−y
1+1
):max→a
nsmax⎩⎪⎪
⎪⎨⎪⎪
⎪⎧s
t[x1
][y
1][
p][q
]→w1
st[
x2−
2p+1
][y1
][p
][q]
→w2
st[x
1][
y2−
2q+1
][p]
[q]→
w3s
t[x2
−2p
+1][
y2−
2q+1
]→w4
}→
ans答案就為上面四個矩陣的max
max
,所以預處理對數,每次o(1
)o(1
)回答即可。
那麼總的複雜度為o(n
mlog
nlog
m+q)
o(nm
logn
logm
+q),是可以過的了。
**:
#include
#include
#include
using
namespace std;
const
int log=12;
const
int n=
610;
const
int inf=
1e9;
int n,m,q;
int maxv[log]
[log]
[n][n]
;int pre[n]
,val[n]
[n];
void
init()
}}}}
intquery
(int x1,
int y1,
int x2,
int y2)
int x1,x2,y1,y2;
intmain()
return0;
}
二維RMQ模板
int main for int i 0 1 i n i 因為i 0時的 和 i 0 j 0時的一樣 所以就合併了 i 0 j 0時 查詢 詢問的話,也要稍加改變,一維rmq返回的是一段區間的最值,而二維的rmq需要返回的乙個矩陣的最值,所以返回的時候要注意,所返回的一定要構成乙個矩陣 按照一維rm...
ST表求解靜態RMQ 二維RMQ 模版
rmq range minimum query 範圍最小值問題。具體表現為一下一類問題 給出乙個 n 個元素的陣列 a1,a2,a na1,a2,an a1,a2,an 求解 min l,r min l,r min l,r 計算 min al,a l 1,ar minmi nal,al 1 arrm...
zoj 3614 二維RMQ 容斥
rmq求出矩陣區間最大,陣列sum和pro分別存座標i,j到右下角的矩陣所有元素和,和平方和,然後根據容斥求出某一矩陣的元素和,平方和。然後根據方差展開求最大座標,就ok啦。include include include include include include include include...