https://ac.nowcoder.com/acm/contest/883/F?&headNav=acm
枚举上下边界,然后,枚举右边界,合法的矩形左边界关于右边界向右而向右,用单调队列来做。
这题卡RMQ,并且卡STL。
#include
using namespace std;
const int maxn=600;
int T,n,m,a[maxn][maxn],Max[maxn],Min[maxn];
int main()
{
//freopen("input.in","r",stdin);
cin>>T;
while(T--)
{
int ans=0;
cin>>n>>m;
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);
for(int up=1;up<=n;up++)
{
for(int down=up;down<=n;down++)
{
for(int c=1;c<=n;c++)
if(up==down)Max[c]=Min[c]=a[down][c];
else Max[c]=max(Max[c],a[down][c]),Min[c]=min(Min[c],a[down][c]);
int qmax[maxn],qmin[maxn],smin=1,tmin=0,smax=1,tmax=0;
int l=1;
for(int r=1;r<=n;r++)
{
while(smin<=tmin && Min[qmin[tmin]]>=Min[r])tmin--;
while(smax<=tmax && Max[qmax[tmax]]<=Max[r])tmax--;
qmax[++tmax]=qmin[++tmin]=r;
while(smin<=tmin && smax<=tmax && Max[qmax[smax]]-Min[qmin[smin]]>m)
{
if(qmin[smin]==l)smin++;
if(qmax[smax]==l)smax++;
l++;
}
ans=max(ans,(down-up+1)*(r-l+1));
}
}
}
cout<<ans<<endl;
}
return 0;
}