Planting Trees

Planting Trees

给定N*N矩阵,求子矩形满足里面最大元素最小元素之差不超过M

单调队列

枚举上边界,下边界,及右边界,

用两个单调队列,一个维护最大值,一个维护最小

求左边界

#include<bits/stdc++.h>
using namespace std;
int A[505][505];
#define sc(x) scanf("%d",&x);
int ma[505];
int mi[505];
int q1[505];
int q2[505];
int main()
{
    int T,N,M;
    sc(T);
    while(T--){
    sc(N);sc(M);
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            sc(A[i][j]);
        }
    }
    int ans=1;
    for(int i=1;i<=N;i++){///
        for(int j=1;j<=N;j++)ma[j]=0,mi[j]=1e5+7;
        for(int j=i;j<=N;j++){///
            for(int k=1;k<=N;k++){///
                ma[k]=max(ma[k],A[j][k]);
                mi[k]=min(mi[k],A[j][k]);
            }
            
            int l1=0,l2=0,r1=0,r2=0;
            for(int k=1,p=0;k<=N;k++){
                    for(;l1<r1&&ma[q1[r1-1]]<ma[k];)r1--;
                    for(;l2<r2&&mi[q2[r2-1]]>mi[k];)r2--;
                    q1[r1++]=k,q2[r2++]=k;
                    for(;l1<r1&&l2<r2&&ma[q1[l1]]-mi[q2[l2]]>M;){
                        if(q1[l1]<q2[l2])p=q1[l1++];
                        else p=q2[l2++];
                    }//p位置不取
                    ans=max(ans,(j-i+1)*(k-p));
               }
        }
    }
    cout<<ans<<'
';
    }
}
原文地址:https://www.cnblogs.com/liulex/p/11365281.html