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
长度为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]); }