hdu5696 区间的价值

Posted WQHui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",ans[i]);
}

 

 

以上是关于hdu5696 区间的价值的主要内容,如果未能解决你的问题,请参考以下文章

HDU5696 区间的价值

[hdu] 5696 区间的价值 || 序列分治

HDU 5696 ——区间的价值——————线段树快排思想

hdu5696区间的价值 -- 2016"百度之星" - 初赛(Astar Round2B)

ACM学习历程—HDU5696 区间的价值(分治 && RMQ && 线段树 && 动态规划)

Hdu 5696 区间价值(2016百度之星初赛Astar Round2B )(线段树)