题意: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. Maven+JSP+Servlet+JDBC+Redis+Mysql实现的黑马旅游网

    项目简介 项目来源于:https://gitee.com/haoshunyu/travel 本系统是基于Maven+JSP+Servlet+JdbcTemplate+Redis+Mysql实现的旅游网 ...

  2. Flutter Weekly Issue 52

    教程 一个易迁移.兼容性高的 Flutter 富文本方案 复杂业务如何保证Flutter的高性能高流畅度? 插件 flutter_color_models A wrapper for the Dart ...

  3. 详解 List接口

    本篇博文所讲解的这两个类,都是泛型类(关于泛型,本人在之前的博文中提到过),我们在学习C语言时,对于数据的存储,用的差不多都是数组和链表. 但是,在Java中,链表就相对地失去了它的存在价值,因为Ja ...

  4. 异常体系结构 throwable

    package com.yhqtv.demo01Exception; /* * 一.异常体系结构 *java.lang.Throwable * ------java.lang.Error:一般不编写针 ...

  5. 分析 Nanocore

    Nanocore是一个非常强大的木马控制系统,当Nanocore木马运行时,我们发现Windows Defender可以很好地识别威胁.本文的目的是分析Nanocore的传播方式,它是怎样感染Wind ...

  6. 将jar包发布到maven中央仓库

    将jar包发布到maven中央仓库 最近做了一个swagger-ui的开源项目,因为是采用vue进行解析swagger-json,需要前端支持,为了后端也能方便的使用此功能,所以将vue项目编译后的结 ...

  7. java 之 enum(枚举)

    推荐博客 http://blog.csdn.net/javazejian/article/details/71333103

  8. .net多线程归并排序

    一.概述 在了解排序算法的同时,想到用多线程排序减少排序的时间,所以写了一个简单的示例,加深印象.下面是具体代码 二.内容 环境:vs2017,.net  core 2.2 控制台程序. 运行时使用r ...

  9. VR全景视图 Google VrPanoramaView

    2019独角兽企业重金招聘Python工程师标准>>> 一.背景简介 Welcome to VR at Google 进入Google VR主页,发现官方给我们提供了两套解决观看VR ...

  10. 【Netapp】在模拟器中使用disk removeowner报错

    报错信息如下: Cluster2::storage disk*> removeowner NET-1.43 Error: command failed: Disk NET-1.43 is not ...