More than 2019 cattle off summer school camp (third) F.Planting Trees (monotone queue)

Meaning of the questions: to give you a high degree of n * n matrix to find you inside the biggest matrix and can not exceed the maximum height difference m

Ideas: We first enumerate down the right boundary, then we can use to maintain a monotonous queue leftmost boundary and then calculate the maximum time complexity is O (n * n * n)

#include<bits/stdc++.h>
#define ll long long
const int inf = 0x3f3f3f3f;
const int N = 507;
const ll mod = 998244353;
using namespace std;
int a[N][N];
int q1[N],q2[N],minn[N],maxx[N];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t; cin>>t;
    while(t--){
        int n,m; cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                cin>>a[i][j];
        int ans=0;
        for(int i=1;i<=n;i++){
            memset(maxx,-1,sizeof(maxx));
            memset(minn,inf,sizeof(minn));
            for(int j=i;j<=n;j++){
                for(int k=1;k<=n;k++){
                    maxx[k]=max(maxx[k],a[j][k]);
                    minn[k]=min(minn[k],a[j][k]);
                }
                int l1,l2,r1,r2;
                l1=l2=1; r1=r2=0;
                int po=1;
                for(int k=1;k<=n;k++){
                    while(l1<=r1&&maxx[k]>=maxx[q1[r1]]) --r1;
                    q1[++r1]=k;
                    while(l2<=r2&&minn[k]<=minn[q2[r2]]) --r2;
                    q2[++r2]=k;
                    while(l1<=r1&&l2<=r2&&maxx[q1[l1]]-minn[q2[l2]]>m){
                        po=min(q1[l1]+1,q2[l2]+1);
                        while(l1<=r1&&q1[l1]<po)
                            ++l1;
                        while(l2<=r2&&q2[l2]<po)
                            ++l2;
                    }
                    ans=max(ans,(j-i+1)*(k-po+1));
                }
            }
        }
        cout<<ans<<endl;
    } 
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/wmj6/p/11249823.html