标签:max string ;; define getch [1] 节点 queue turn
【题目分析】
本来是单调栈的题目,用笛卡尔树可以快速的水过去。
把每一个矩阵看成一个二元组(出现的顺序,高度)。
然后建造笛卡尔树。
神奇的发现,每一个节点的高度*该子树的大小,就是这一块最大的子矩阵的可能解。
用二元组的第一个下标来限制,使它们在一块儿,然后堆的性质又限制了宽度以及高度。
计算,取最值即可。
【代码】
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <string> #include <algorithm> #include <vector> #include <iostream> #include <queue> using namespace std; #define maxn 100005 #define ll long long int read() { int x=0,f=1; char ch=getchar(); while (ch<‘0‘||ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} while (ch>=‘0‘&&ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} return x*f; } struct node{ int id,h; }a[maxn]; int sta[maxn],top=0,ch[maxn][2],fa[maxn],siz[maxn],n,rt; void dfs(int k) { if (!k) return ; dfs(ch[k][0]); dfs(ch[k][1]); siz[k]=siz[ch[k][0]]+siz[ch[k][1]]+1; } int main() { while (scanf("%d",&n)!=EOF&&n) { for (int i=1;i<=n;++i) ch[i][0]=ch[i][1]=fa[i]=0; for (int i=1;i<=n;++i) a[i].h=read(),a[i].id=i; ch[1][0]=ch[1][1]=fa[1]=0; top=0; sta[++top]=1; siz[1]=1; rt=1; for (int i=2;i<=n;++i) { int flag=0,now; while (top&&a[sta[top]].h>a[i].h) now=sta[top--],flag=1; if (!flag) { ch[a[sta[top]].id][1]=i; fa[i]=a[sta[top]].id; sta[++top]=i; } else { if (top) { int z=ch[a[sta[top]].id][1]; ch[a[sta[top]].id][1]=i; fa[i]=a[sta[top]].id; ch[i][0]=z; fa[z]=i; sta[++top]=i; } else { fa[now]=i; rt=i; ch[i][0]=now; sta[++top]=i; } } } dfs(rt); ll ans=0; for (int i=1;i<=n;++i) ans=max(ans,(ll)siz[i]*(ll)a[i].h); printf("%lld\n",ans); } }
POJ 2559 Largest Rectangle in a Histogram ——笛卡尔树
标签:max string ;; define getch [1] 节点 queue turn
原文地址:http://www.cnblogs.com/Muliphein/p/6204738.html