• UVA-1619 Feel Good (单调队列)


    题目大意:给一个非负整数序列,求出一个使得区间和乘以区间最小值最大的区间。

    题目分析:单调队列。维护两个数组,l[i]表示以a[i]为最小值的左半区间的最左边端点,r[i]表示以a[i]为最小值的右半区间的最右边端点,l[i]和r[i]合起来便是以a[i]为最小值的整个区间。枚举一遍 i 即可。

    注意:UVA上的这道题有个大大的坑,明明说可以输出任意一个区间(多个解时),实际上是骗人的!!!

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define LL long long
    
    struct Num
    {
        int val,id;
    };
    Num a[100005],que[100005];
    int n,Left[100005],Right[100005];
    long long sum[100005];
    
    void f()
    {
        int head=0,tail=-1;
        for(int i=1;i<=n;++i){
            Left[i]=i;
            while(head<=tail&&que[tail].val>=a[i].val)
                --tail;
            if(head<=tail)
                Left[i]=que[tail].id+1;
            else
                Left[i]=1;
            que[++tail]=a[i];
        }
        head=0,tail=-1;
        for(int i=n;i>=1;--i){
            Right[i]=i;
            while(head<=tail&&que[tail].val>=a[i].val)
                --tail;
            if(head<=tail)
                Right[i]=que[tail].id-1;
            else
                Right[i]=n;
            que[++tail]=a[i];
        }
    }
    
    int main()
    {
        int flag=0,p;
        while(~scanf("%d",&n))
        {
            if(flag)
                printf("
    ");
            flag=1;
            sum[0]=0;
            for(int i=1;i<=n;++i){
                scanf("%d",&a[i].val);
                a[i].id=i;
                sum[i]=(LL)a[i].val+sum[i-1];
            }
            f();
            int ansl,ansr;
            long long ans=-1;
            for(int i=1;i<=n;++i)
                if(ans<(LL)a[i].val*(sum[Right[i]]-sum[Left[i]-1]))
                    ans=(LL)a[i].val*(sum[Right[i]]-sum[Left[i]-1]),ansl=Left[i],ansr=Right[i];
            printf("%lld
    ",ans);
            if(ans==0)
                printf("1 1
    ");
            else
                printf("%d %d
    ",ansl,ansr);
        }
        return 0;
    }
    

      

  • 相关阅读:
    html5调用手机本地摄像头和相册识别二维码详细实现过程(附源码下载)
    settings.json
    vue echarts中引入图片
    [SQL Server]储存过程中使用临时表循环操作数据
    前端图标 框架
    Word 简便使用方法
    未能加载文件或程序集“Interop.Excel”或它的某一个依赖项。拒绝访问。
    硬盘完美分区
    DataTable的Distinct的简易方法
    用正则判断字符串是否为数字
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4878900.html
Copyright © 2020-2023  润新知