zoukankan      html  css  js  c++  java
  • 牛客多校第三场F Planting Trees 单调栈

    Planting Trees

    题意

    给出一个矩阵,求最大矩阵面积满足该矩阵中任2元素的绝对值之差小于等于M T<1000) (n<500)但是题目明示单组(n*3)可过

    分析

    又是矩阵问题,单调栈的第n次出现?这一题和之前的题不同的是,边界界定没有以前那么直白,变成了绝对值的问题,绝对值问题可以转化成最大最小的问题,那么如何枚举矩阵呢?不同于之前的简单的连续性可以传递的矩阵问题,这一题要枚举矩阵的上下边界,那枚举了上下边界如果计算当前上下边界上的矩形的最大面积,那就要用到单调栈了,固定上边界维护每一列的最大值最小值,并以此值来维护单调队列,以一个类似双指针的形式即可求出最大值。

    #include<bits/stdc++.h>
    using namespace std;
    #define F first
    #define S second
    const int maxn=500+5;
    int q1[maxn],q2[maxn],a[maxn][maxn],rowmin[maxn],rowmax[maxn];
    int n,m,t;
    long long ans=0;
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            ans=0;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    scanf("%d",&a[i][j]);
                }
            }
            for(int i=1;i<=n;i++){
                for(int k=1;k<=n;k++)rowmin[k]=rowmax[k]=a[i][k];
                for(int j=i;j<=n;j++){
                int head1=1,tail1=0;
                int head2=1,tail2=0;
                    for(int k=1;k<=n;k++){
                        rowmin[k]=min(rowmin[k],a[j][k]);
                        rowmax[k]=max(rowmax[k],a[j][k]);
                    }
                    int l=1;
                    for(int k=1;k<=n;k++){
                        if(tail1<head1){
                            q1[++tail1]=k;
                        }
                        else {
                            while(tail1>=head1&&rowmin[k]<=rowmin[q1[tail1]])tail1--;
                            q1[++tail1]=k;
                        }
                        if(tail2<head2){
                            q2[++tail2]=k;
                        }
                        else {
                            while(tail2>=head2&&rowmax[k]>=rowmax[q2[tail2]])tail2--;
                            q2[++tail2]=k;
                    }
                        while(l<=k&&rowmax[q2[head2]]-rowmin[q1[head1]]>m){
                            l++;
                            if(q2[head2]<l)head2++;
                            if(q1[head1]<l)head1++;
                        }
                        ans=max(ans,1ll*(k-l+1)*(j-i+1));
                 
                }
            }
            }
                cout<<ans<<endl;
        }
     
         
        return 0;
    }
    
  • 相关阅读:
    设计模式一 Simple Factory, Factory Method, Abstract Factory以及Builder模式简述
    SQL Server中对XML操作
    开发常用小工具介绍
    强制休息程序 EyeGuardian 眼睛守护者 Beta测试版
    定时计划任务方案比较以及通过脚本创建计划任务(SchTasks命令)
    在Myeclipse中配置Maven
    Jena的环境配置
    0x01_go代码简单示例
    0x00_go语言安装
    信息收集工具
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/11396007.html
Copyright © 2011-2022 走看看