hdu1506 Largest Rectangle in a Histogram (笛卡尔树)

来源:互联网 发布:2g3g4g网络 编辑:程序博客网 时间:2024/06/06 07:29

传送门: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;}
0 0