• hdu 5696 区间的价值 单调栈+rmq


    区间的价值

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)


    Problem Description
     
    我们定义“区间的价值”为一段区间的最大值*最小值。

    一个区间左端点在L,右端点在R,那么该区间的长度为(RL+1)

    现在聪明的杰西想要知道,对于长度为k的区间,最大价值的区间价值是多少。

    当然,由于这个问题过于简单。

    我们肯定得加强一下。

    我们想要知道的是,对于长度为1n的区间,最大价值的区间价值分别是多少。

    样例解释:

    长度为1的最优区间为22 答案为66

    长度为2的最优区间为45 答案为44

    长度为3的最优区间为24 答案为26

    长度为4的最优区间为25 答案为26

    长度为5的最优区间为15 答案为16
     
    Input
    多组测试数据

    第一行一个数n(1n100000)

    第二行n个正整数(1ai109),下标从1开始。

    由于某种不可抗力,ai的值将会是1109内<b style="color:red;">随机产生</b>的一个数。(除了样例)
     
    Output
    输出共n行,第i行表示区间长度为i的区间中最大的区间价值。
     
    Sample Input
    5 1 6 2 4 4
     
    Sample Output
    36 16 12 12 6
     
    Source
    思路:利用单调栈得到以a[i]为最小值的区间左端点和右端点;
       发现a[i]*该区间的最大值,为该区间的最小值;
       举个例子;
       5
       1 6 2 4 4
             以2为区间最小值,该区间为[2,5];
       在[2,5]区间长度为4,发现在这区间内长度为3,2,1都比2*6=12大;
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define mod 100000007
    #define esp 0.00000000001
    const int N=1e5+10,M=1e6+10,inf=1e9+10;
    ll sum[N<<2];
    ll a[N<<2];
    int d[N];
    int l[N];
    int r[N];
    ll ans[N];
    void build(int l,int r,int pos)
    {
        if(l==r)
        {
            sum[pos]=a[l];
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid,pos<<1);
        build(mid+1,r,pos<<1|1);
        sum[pos]=max(sum[pos<<1],sum[pos<<1|1]);
    }
    ll query(int L,int R,int l,int r,int pos)
    {
        if(L<=l&&R>=r)
        return sum[pos];
        int mid=(l+r)>>1;
        ll ans=0;
        if(R>mid)ans=max(ans,query(L,R,mid+1,r,pos<<1|1));
        if(L<=mid)ans=max(ans,query(L,R,l,mid,pos<<1));
        return ans;
    }
    int main()
    {
        int x,y,z,i,t;
        while(~scanf("%d",&x))
        {
            memset(ans,0,sizeof(ans));
            for(i=1;i<=x;i++)
            scanf("%I64d",&a[i]);
            build(1,x,1);
            a[0]=a[x+1]=0;
            int k=0;
            d[++k]=0;
            for(i=1;i<=x;i++)
            {
                while(a[d[k]]>=a[i])k--;
                l[i]=d[k];
                d[++k]=i;
            }
            k=0;
            d[++k]=x+1;
            for(i=x;i>=1;i--)
            {
                while(a[d[k]]>=a[i])k--;
                r[i]=d[k];
                d[++k]=i;
            }
            for(i=1;i<=x;i++)
            ans[r[i]-l[i]-1]=max(ans[r[i]-l[i]-1],(ll)query(l[i]+1,r[i]-1,1,x,1)*a[i]);
            for(i=x-1;i>=1;i--)
            ans[i]=max(ans[i],ans[i+1]);
            for(i=1;i<=x;i++)
            printf("%I64d
    ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    STM32F107的DAC配置
    步进电机工作原理
    winform笔记本蓝牙与外部蓝牙设备通信
    C#里三种强制类型转换
    IE6/7BUG之OL有序列表没顺序
    IE6/7BUG之列表UL楼梯
    IE6/7BUG之A超链接无效
    IE6/7BUG之overflow:hidden无效
    linux shell 管道命令(pipe)使用及与shell重定向区别
    UGUI研究院之全面理解图集与使用
  • 原文地址:https://www.cnblogs.com/jhz033/p/5664669.html
Copyright © 2020-2023  润新知