POJ2559 单调队列

题目大意:给定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;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值