POJ2559 单调队列

来源:互联网 发布:网络摄像头存储计算 编辑:程序博客网 时间:2024/05/17 08:13

题目大意:给定n个连续的宽度为1的矩形,求最大子矩形面积。

求一遍每个点向右延伸的最长长度,再反着求一遍每个点向左延伸的最长长度,两个加起来(要减去重复计算的本身长度),取最优解。

这题为什么会WA呢?因为可能会有长度为0的矩形,这时候必须往队列里push个-1才能把它弹出来。。。而如果不把它弹出来,它的延伸长度就会遗留上一组数据的(没有被变成0)而导致错误。。。

自己的代码:

#include<cstdio>using namespace std;typedef unsigned long long ull;int n,a[100002]={},top;ull l[100002],r[100002];int stk[100002];inline int abs(int x){return x>>31?-x:x;}void push(int no,ull t[]){    while(~top&&a[no]<a[stk[top]])    t[stk[top]]=ull(a[stk[top]])*abs(no-stk[top]),top--;    stk[++top]=no;}int main(){    while(scanf("%d",&n)==1)    {        if(!n) break;        a[0]=a[n+1]=-1;        for(int i=1;i<=n;i++)        scanf("%d",&a[i]);        top=-1;        for(int i=1;i<=n;i++)        push(i,l);        push(n+1,l);        top=-1;        for(int i=n;i>=1;i--)        push(i,r);        push(0,r);        ull ans=0;        for(int i=1;i<=n;i++)        if(l[i]+r[i]-a[i]>ans) ans=l[i]+r[i]-a[i];        printf("%llu\n",ans);    }    return 0;}
0 0
原创粉丝点击