• hdu5696 区间的价值


    区间的价值

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

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

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

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

    我们肯定得加强一下。

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

    样例解释:
    长度为1的最优区间为2-2  答案为6*6 
    长度为2的最优区间为4-5  答案为4*4 
    长度为3的最优区间为2-4  答案为2*6 
    长度为4的最优区间为2-5  答案为2*6 
    长度为5的最优区间为1-5  答案为1*6 

    Input单组测试数据 
    第一行一个数n(1<=n<=100000)。 
    第二行n个正整数(1<=ai<=10^9),下标从1开始。 
    由于某种不可抗力,ai的值将会是1~10^9内随机的一个数。(除了样例)Output输出共n行,第i行表示区间长度为i的区间中最大的区间价值。Sample Input

    5
    1 6 2 4 4

    Sample Output

    36
    16
    12
    12
    6

    先用线段树维护出区间最小值和最大值;
    用快排的分治思想;
    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    using namespace std;
    
    long long n,m,r,ans[100008],tree_max[400008],tree_min[400008];
    long long a[100008];
    
    void build(int l,int r,int v){
        if(l==r){
            tree_max[v]=l;
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid,v<<1);
        build(mid+1,r,(v<<1)+1);
        if(a[tree_max[v<<1]]>a[tree_max[(v<<1)+1]])
            tree_max[v]=tree_max[v<<1];
        else
            tree_max[v]=tree_max[(v<<1)+1];
    }
    
    void build1(int l,int r,int v){
        if(l==r){
            tree_min[v]=l;
            return;
        }
        int mid=(l+r)>>1;
        build1(l,mid,v<<1);
        build1(mid+1,r,(v<<1)+1);
        if(a[tree_min[v<<1]]<a[tree_min[(v<<1)+1]])
            tree_min[v]=tree_min[v<<1];
        else
            tree_min[v]=tree_min[(v<<1)+1];
    }
    
    long long query(int l,int r,int x,int y,int v){
        if(l==x&&r==y){
            return tree_max[v];
        }
        int mid=(l+r)>>1;
        if(y<=mid) return query(l,mid,x,y,v<<1);
        if(x>mid) return query(mid+1,r,x,y,(v<<1)+1);
        long long aa=query(l,mid,x,mid,v<<1);
        long long bb=query(mid+1,r,mid+1,y,(v<<1)+1);
        if(a[aa]>a[bb])
            return aa;
        else
            return bb;
    }
    
    long long query1(int l,int r,int x,int y,int v){
        if(l==x&&r==y){
            return tree_min[v];
        }
        int mid=(l+r)>>1;
        if(y<=mid) return query1(l,mid,x,y,v<<1);
        if(x>mid) return query1(mid+1,r,x,y,(v<<1)+1);
        long long aa=query1(l,mid,x,mid,v<<1);
        long long bb=query1(mid+1,r,mid+1,y,(v<<1)+1);
        if(a[aa]<a[bb])
            return aa;
        else
            return bb;
    }
    
    void dfs(int l,int r){
        if(r<l) return;
        long long aa=query(1,n,l,r,1);
        long long bb=query1(1,n,l,r,1);
        if(aa>bb) swap(aa,bb);
        long long k=a[aa]*a[bb];
        for(int i=(bb-aa)+1;i<=r-l+1;i++)
            ans[i]=max(ans[i],k);
        if(a[bb]>a[aa])
            dfs(aa+1,r),dfs(l,aa-1);
        else
            dfs(bb+1,r),dfs(l,bb-1);
    }
    
    int main(){
        scanf("%lld",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        build(1,n,1);
        build1(1,n,1);
        dfs(1,n);
        for(int i=1;i<=n;i++)
            printf("%lld
    ",ans[i]);
    }
    
    
    
     
    
    
  • 相关阅读:
    1226 倒水问题
    1230 元素查找
    2152 滑雪
    1099 字串变换 2002年NOIP全国联赛提高组
    3027 线段覆盖 2
    P2066 机器分配
    spring的作用及优势---第一个spring示例
    密码框显示提示文字
    紫薇~还记得大明湖畔的HTML5智力拼图吗?
    细说javascript函数
  • 原文地址:https://www.cnblogs.com/WQHui/p/7683407.html
Copyright © 2020-2023  润新知