我们定义“区间的价值”为一段区间的最大值*最小值。
一个区间左端点在 L ,右端点在 R ,那么该区间的长度为 (R−L+1) 。
现在聪明的杰西想要知道,对于长度为 k 的区间,最大价值的区间价值是多少。
当然,由于这个问题过于简单。
我们肯定得加强一下。
我们想要知道的是,对于长度为 1∼n 的区间,最大价值的区间价值分别是多少。
一个区间左端点在 L ,右端点在 R ,那么该区间的长度为 (R−L+1) 。
现在聪明的杰西想要知道,对于长度为 k 的区间,最大价值的区间价值是多少。
当然,由于这个问题过于简单。
我们肯定得加强一下。
我们想要知道的是,对于长度为 1∼n 的区间,最大价值的区间价值分别是多少。
分析:枚举以该点为最小值,然后找到最大值,更新,相应数组,至此,把区间分割(因为包含这个最小值点已经枚举过),递归写法即可
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-10
#define maxn 1000010
#define MOD 1000000007
typedef long long LL;
const int N=1e5+5;
int a[N],n;
LL res[N];
void dfs(int l,int r){
if(l>r)return;
if(l==r){res[1]=max(res[1],1ll*a[l]*a[l]);return;}
int k1,k2;k1=k2=l;
for(int i=l;i<=r;++i){
if(a[i]<a[k1])k1=i;
if(a[i]>a[k2])k2=i;
}
res[r-l+1]=max(res[r-l+1],1ll*a[k1]*a[k2]);
dfs(l,k1-1);
dfs(k1+1,r);
}
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;++i)
scanf("%d",&a[i]),res[i]=0;
dfs(1,n);
for(int i=n-1;i>0;--i)
res[i]=max(res[i],res[i+1]);
for(int i=1;i<=n;++i)
printf("%I64d\n",res[i]);
}
return 0;
}