【jzoj4820】【最大化】【单调栈】

来源:互联网 发布:linux echo输出到文件 编辑:程序博客网 时间:2024/06/05 08:27

题目大意

这里写图片描述

解题思路

枚举左右边界,压成一维做前缀和,维护一个单调递减的栈,从后往前做,对答案有贡献的是小于它的最前点,如果比上一个大则继续退栈,比上一个小则不可能对答案贡献,因为和它匹配的点序号更大,区间长度更小。

code

#include<set>#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#define LF double#define LL long long#define max(n1,n2) ((n1>n2)?n1:n2)#define min(n1,n2) ((n1>n2)?n2:n1)#define num(n1,n2) ((n1-1)*3*n+n2+1)#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)using namespace std;int const maxn=300,inf=2147483647;int n,m,l,r;LL x,s[maxn+10][maxn+10],sum[maxn+10],a[maxn+10],b[maxn+10];int main(){    freopen("d.in","r",stdin);    freopen("d.out","w",stdout);    scanf("%d%d",&n,&m);    fo(i,1,n)        fo(j,1,m)            scanf("%lld",&x),s[i][j]=s[i][j-1]+x;    LL ans=1;    fo(i,0,m)        fo(j,i+1,m){            a[0]=0;            fo(k,1,n){                sum[k]=sum[k-1]+s[k][j]-s[k][i];                if(sum[k]<a[a[0]])a[++a[0]]=sum[k],b[a[0]]=k;            }            fd(k,n,1)                if(a[a[0]]<sum[k]){                    for(;a[0]&&(a[a[0]-1]<sum[k]);a[0]--);                    ans=max(ans,(k-b[a[0]])*(j-i));                }        }    printf("%lld",ans);    return 0;}
0 0
原创粉丝点击