二維RMQ問題

2022-05-16 10:25:56 字數 3877 閱讀 5753

前置知識

一維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]

=max⁡s

t[i]

[j][

k][l

]=max其中,max

⁡max

裡面第乙個為上半部分矩陣,後面乙個為下半部分矩陣。

如果l=0l

=0的話,就將其豎起剖成兩部分即可,是同理的。轉移如下:st

[i][

j][k

][l]

=max⁡s

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]→

w3​s

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...