2019牛客暑期多校训练营(第三场)F. Planting Trees

题目大意:给出一个N*N的方阵,每个点有高度,圈出一个面积尽可能大的矩形满足(最大高度-最小高度)<=M.

思路:单调队列+枚举。枚举上下边界,对于固定上下边界枚举右端点,对于每个右端点求出最左端的满足条件的位置,计算矩形面积。用两个数组维护每一列(上边界到下边界)的最大最小值,通过两个单调队列维护单调递增和单调递减的下标(右端点右移时改变队尾)。

链接:https://ac.nowcoder.com/acm/contest/883/F

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
struct edge{
    ll p,l,r,maxv,minv;
};
const int N=505;
int maxa[N];
int mina[N];
int a[N][N];
const ll INF=1e9+7;
#define pii pair<int,int>
int main(){
    int t;cin>>t;
    while(t--){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin>>a[i][j];
            }
        }
        ll ans=0;
        for(int up=1;up<=n;up++){
            for(int i=1;i<=n;i++){
                maxa[i]=0;
                mina[i]=INF;
            }
            for(int down=up;down<=n;down++){
                for(int i=1;i<=n;i++){
                    maxa[i]=max(maxa[i],a[down][i]);
                    mina[i]=min(mina[i],a[down][i]);
                }
                deque<pii>q1,q2;
                int l=1;
                for(int i=1;i<=n;i++){
                    //cout<<maxa[i]<<endl;
                    //cout<<mina[i]<<endl;
                    while(!q1.empty()&&q1.back().second<maxa[i])q1.pop_back();
                    q1.push_back(make_pair(i,maxa[i]));
                    while(!q2.empty()&&q2.back().second>mina[i])q2.pop_back();
                    q2.push_back(make_pair(i,mina[i]));
                    while(!q1.empty()&&!q2.empty()&&q1.front().second-q2.front().second>m){
                        if(q1.front().first<=q2.front().first){
                            l=q1.front().second+1;
                            q1.pop_front();
                            //if(!q1.empty())l=max(l,q1.front().first);
                            //if(!q2.empty())l=max(l,q2.front().first);
                        }else{
                            l=q2.front().second+1;
                            q2.pop_front();
                            //if(!q1.empty())l=max(l,q1.front().first);
                            //if(!q2.empty())l=max(l,q2.front().first);
                        }
                    }
                    if(!q1.empty()&&!q2.empty()){
                        //cout<<q1.front().second<<' '<<q2.front().second<<' '<<q1.front().first<<' '<<q2.front().first<<endl;
                        //cout<<"U D"<<up<<' '<<down<<endl;
                        //cout<<"L R:"<<l<<' '<<i<<endl;
                        ans=max(ans,1ll*(i-l+1)*(down-up+1));
                    }
                }
            }
        }
        cout<<ans<<"\n";
    }
    return 0;
}

 

posted @ 2019-08-09 15:45  八佾舞雩  阅读(124)  评论(0)    收藏  举报