首页 > 技术文章 > RMQ-二维ST表 专题训练

tldr 2019-07-29 12:53 原文

没看过一维ST表的可以移步
https://www.cnblogs.com/tldr/p/11261351.html
二维ST表的思路参考一维,每次维护一个step*step的一个正方形
因此 洛谷P2216理想的正方形是一个很好的二维ST表
一般来说,二维ST表询问的是某一个状态,这样可以用一个二维数组存下,否则就需要三维数组了,内存和时间消耗特别大

#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define FOR2(i,a,b) for(int i=a;i<=b;i++)
#define sync ios::sync_with_stdio(false);cin.tie(0) 
#define ll long long
#define INF  0x3f3f3f3f;
#define MAXN 1000100
#define MOD 10007
#define sf(a,b) read(a),read(b)
using namespace std;
int a,b,k,arr[1100][1100],dpmax[1100][1100],dpmin[1100][1100];
int main()
{//AC
	cin>>a>>b>>k;int logk=log2(k);
	//read
	FOR2(i,1,a)
		FOR2(j,1,b)scanf("%d",&arr[i][j]),dpmin[i][j]=dpmax[i][j]=arr[i][j];
	//process
	for(int h=1;h<=logk;h++)
		for(int i=1;i+(1<<h)-1<=a;i++)
			for(int j=1;j+(1<<h)-1<=b;j++)
				{	
					dpmax[i][j]=max(dpmax[i][j],max(dpmax[i+(1<<h-1)][j],max(dpmax[i+(1<<h-1)][j+(1<<h-1)],dpmax[i][j+(1<<h-1)])));
					dpmin[i][j]=min(dpmin[i][j],min(dpmin[i+(1<<h-1)][j],min(dpmin[i+(1<<h-1)][j+(1<<h-1)],dpmin[i][j+(1<<h-1)])));
				}
	//query
	int res=INF;
	for(int i=1;i<=a-k+1;i++)
		for(int j=1;j<=b-k+1;j++)
		{
			int maxx=max(dpmax[i][j],max(dpmax[i+k-(1<<logk)][j],max(dpmax[i+k-(1<<logk)][j+k-(1<<logk)],dpmax[i][j+k-(1<<logk)])));
			int minn=min(dpmin[i][j],min(dpmin[i+k-(1<<logk)][j],min(dpmin[i+k-(1<<logk)][j+k-(1<<logk)],dpmin[i][j+k-(1<<logk)])));
			res=min(res,maxx-minn);
		}
		cout<<res<<endl;
	return 0;
}

推荐阅读