赞
踩
传送门: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;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。