傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=1506
標解應該是DP。不過這裏可以當做笛卡爾樹模板題來做。笛卡爾樹的構造方式爲:首先我們按照橫座標從左往右進行處理,同時維護一個單調棧,保證棧裏的元素高度遞增。每次進來一個新的節點時,將棧裏比它高的元素都彈出,並將它的左兒子設爲最後一個彈出的節點,而且將先彈出的節點設爲它之後彈出的那個節點的右兒子即可。爲了保證結束性,可以在最右側加入一個高度爲0的點。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
typedef long long LL;
struct node
{
int x,y;
};
int n;
int a[110000];
stack<node> s;
int ch[110000][2],fa[110000],sz[110000];
int root;
void build(int n)
{
memset(ch,0,sizeof(ch));
memset(fa,0,sizeof(fa));
for (int i=1;i<=n;i++)
{
int last=0;
while (!s.empty()&&s.top().y>=a[i])
{
if (last) ch[s.top().x][1]=last,fa[last]=s.top().x;
last=s.top().x;
s.pop();
}
if (last&&i!=n) ch[i][0]=last,fa[last]=i;
if (i!=n) s.push({i,a[i]});
}
root=1;
while(fa[root]) root=fa[root];
}
LL ans;
void dfs(int x)
{
sz[x]=1;
for (int i=0;i<2;i++)
if (ch[x][i]) dfs(ch[x][i]),sz[x]+=sz[ch[x][i]];
ans=max(ans,(LL)sz[x]*(LL)a[x]);
}
int main()
{
while (scanf("%d",&n)==1&&n)
{
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
a[n+1]=0;
build(n+1);
ans=0;
dfs(root);
printf("%I64d\n",ans);
}
return 0;
}