题意:http://acm.hdu.edu.cn/showproblem.php?pid=1506 如图,求最大的矩形面积

思路:

笛卡尔树:笛卡尔树是一棵二叉树,树的每个节点有两个值,一个为key,一个为value。光看key的话,笛卡尔树是一棵二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大;光看value的话,笛卡尔树有点类似堆,根节点的value是最小(或者最大)的,每个节点的value都比它的子树要小(或者大)。

笛卡尔树的构造算法:从右链插入,同时维护右链的递增或递减序列。

笛卡尔树的性质:中序遍历得到原序列;对每棵子树,它对应一个区间,并且它的根表示的值就是对应区间的最大值或最小值。

虽然利用单调队列也可以非常快的解决问题,但这里用笛卡尔树做下。令f(x)表示高为x的最大矩形面积,则对每个x,有f(x)=(rmax-lmin+1)*x,其中[lmin,rmax]区间的最小值为x。把下标作为key,a数组对应的值作为value,构造笛卡尔树。在笛卡尔树上,对每个x,lmin和rmax都可以利用子树O(1)得到,而建树复杂度也为O(n),所以总复杂度是O(n)的。

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#pragma comment(linker, "/STACK:10240000")
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull; //#ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
//#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);} const double PI = acos(-1.0);
const int INF = 1e9 + ;
const double EPS = 1e-8; /* -------------------------------------------------------------------------------- */ const int maxn = 1e5 + ; struct CartesianTree {
struct Node {
int key, value, l, r;
Node(int key, int value) {
this->key = key;
this->value = value;
l = r = ;
}
Node() {}
};
Node tree[maxn];
int sz;
stack<int> S;
void build(int a[], int n) {
while (!S.empty()) S.pop();
tree[] = Node(- , - INF);
S.push();
sz = ;
for (int i = ; i < n; i ++) {
tree[++ sz] = Node(i, a[i]);
int last = ;
/** 小根堆 区间最小值*/
while (tree[S.top()].value >= tree[sz].value) {
last = S.top();
S.pop();
}
tree[sz].l = last;
tree[S.top()].r = sz;
S.push(sz);
}
}
Node &operator [] (const int x) {
return tree[x];
}
};
CartesianTree ct; ll ans; int dfs(int rt) {
int cnt = ;
if (ct[rt].l) cnt += dfs(ct[rt].l);
if (ct[rt].r) cnt += dfs(ct[rt].r);
umax(ans, (ll)cnt * ct[rt].value);
return cnt;
} int a[maxn]; int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int n;
while (cin >> n, n) {
for (int i = ; i < n; i ++) {
scanf("%d", a + i);
}
ct.build(a, n);
ans = ;
dfs();
cout << ans << endl;
}
return ;
}

[hdu1506 Largest Rectangle in a Histogram]笛卡尔树的更多相关文章

  1. POJ 2559 Largest Rectangle in a Histogram ——笛卡尔树

    [题目分析] 本来是单调栈的题目,用笛卡尔树可以快速的水过去. 把每一个矩阵看成一个二元组(出现的顺序,高度). 然后建造笛卡尔树. 神奇的发现,每一个节点的高度*该子树的大小,就是这一块最大的子矩阵 ...

  2. hdu 1506 Largest Rectangle in a Histogram——笛卡尔树

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1506 关于笛卡尔树的构建:https://www.cnblogs.com/reverymoon/p/952 ...

  3. hdu---1506(Largest Rectangle in a Histogram/dp最大子矩阵)

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  4. hdu1506——Largest Rectangle in a Histogram

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  5. hdu1506 Largest Rectangle in a Histogram

    Problem Description A histogram is a polygon composed of a sequence of rectangles aligned at a commo ...

  6. HDU1506 Largest Rectangle in a Histogram (动规)

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  7. NYOJ-258/POJ-2559/HDU-1506 Largest Rectangle in a Histogram,最大长方形,dp或者单调队列!

                                         Largest Rectangle in a Histogram 这么经典的题硬是等今天碰到了原题现场懵逼两小时才会去补题.. ...

  8. 【题解】hdu1506 Largest Rectangle in a Histogram

    目录 题目 思路 \(Code\) 题目 Largest Rectangle in a Histogram 思路 单调栈. 不知道怎么描述所以用样例讲一下. 7 2 1 4 5 1 3 3 最大矩形的 ...

  9. HDU-1506 Largest Rectangle in a Histogram【单调栈】

    Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...

随机推荐

  1. 谁说 Vim 不好用?送你一个五彩斑斓的编辑器!

    相信大家在使用各种各样强大的 IDE 写代码时都会注意到,代码中各种类型的关键字会用独特的颜色标记出来,然后形成一套语法高亮规则.这样不仅美观,而且方便代码的阅读. 而在上古神器 Vim 中,我们通常 ...

  2. JavaScript中的作用域和作用域链(边学边写)[看着别人的博客纯手敲]

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域的工作原理.今天这篇文章对JavaScript作用域和作用域链简单的介绍,希望能帮 ...

  3. CISCN love_math和roarctf的easy_clac学习分析

    Love_math 题目源码: <?php error_reporting(0); //听说你很喜欢数学,不知道你是否爱它胜过爱flag if(!isset($_GET['c'])){ show ...

  4. Decision tree——决策树

    基本流程 决策树是通过分次判断样本属性来进行划分样本类别的机器学习模型.每个树的结点选择一个最优属性来进行样本的分流,最终将样本类别划分出来. 决策树的关键就是分流时最优属性$a$的选择.使用所谓信息 ...

  5. MySQL根据业务场景归纳常用SQL语句

    素材表数据:user[{"id":1,"name":"x"},{"id":2,"name":&quo ...

  6. Java的循环语句

    一.while 循环 while(循环条件){ 循环操作语句 } * 循环3要素: 变量的初值.变量的判断.变量的更新 * 缺少循环变量的更新,循环将一直进行下去 public class Whlie ...

  7. embed git commit hash to assembly

    https://stackoverflow.com/a/41200059/3782855 https://github.com/304NotModified/Fody.Stamp

  8. HyperLeger Fabric开发(三)——HyperLeger Fabric架构

    HyperLeger Fabric开发(三)--HyperLeger Fabric架构 一.HyperLeger Fabric逻辑架构 1.HyperLeger Fabric逻辑架构简介 Fabric ...

  9. Vue页面权限控制和动态添加路由

    原文转自:点我 页面权限控制 页面权限控制是什么意思呢? 就是一个网站有不同的角色,比如管理员和普通用户,要求不同的角色能访问的页面是不一样的.如果一个页面,有角色越权访问,这时就得做出限制了. Vu ...

  10. 上传组件Fine Uploader在ASP.NET中的应用

    现如今,世面上流行着许多前端上传组件,例如:Uploadify(http://www.uploadify.com/),Fine Uploader,等等.这篇博客从头开始,介绍如何在ASP.NET MV ...