前言
某次遇到一题需要使用,于是便补充一下。
二维rmq
就是在一个静态矩阵中询问多个子矩阵最值的问题。
具体来说我们可以设状态 fi,j,k,l ,表示左上角 (i,j) ,右下角 (i+2k−1,j+2l−1) 的矩阵的最值。
我们将
k
从
fi,j,k,l=max{fi,j,k,l−1fi,j+2l−1,k,l−1
然后对于查询,因为是询问矩阵,所以要查询四种情况,具体来说如下:
如果查询矩阵左上角为 (x1,y1) ,右下角为 (x2,y2) 。
设 p=log2(x2−x1+1),q=log2(y2−y1+1)
那么:
ans=max⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪fx1,y1,p,qfx1,y1−2q+1,p,qfx1−2p+1,y1,p,qfx1−2p+1,y1−2q+1,p,q
Code
const int N=1000;
int f[11][11][N][N];
int a[N][N];
int n,m;
void pre()
{
fo(i,1,n)
fo(j,1,m) f[0][0][i][j]=a[i][j];
int p=int(log2(n)),q=int(log2(m));
fo(k,0,p)
fo(l,0,q)
if(k+l)
fo(i,1,n-(1<<k)+1)
fo(j,1,m-(1<<l)+1)
if (!l) f[k][l][i][j]=max(f[k-1][l][i][j],f[k-1][l][i+(1<<(k-1))][j]);
else f[k][l][i][j]=max(f[k][l-1][i][j],f[k][l-1][i][j+(1<<(l-1))]);
}
int rmqmax(int x1,int y1,int x2,int y2)
{
int p=int(log2(x2-x1+1)),q=int(log2(y2-y1+1));
return max(max(f[p][q][x1][y1],f[p][q][x2-(1<<p)+1][y1]),max(f[p][q][x1][y2-(1<<q)+1],f[p][q][x2-(1<<p)+1][y2-(1<<q)+1]));
}