题意: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. 杭电 How far away ?

    There are n houses in the village and some bidirectional roads connecting them. Every day peole alwa ...

  2. 教你如何入手用python实现简单爬虫微信公众号并下载视频

    主要功能 如何简单爬虫微信公众号 获取信息:标题.摘要.封面.文章地址 自动批量下载公众号内的视频 一.获取公众号信息:标题.摘要.封面.文章URL 操作步骤: 1.先自己申请一个公众号 2.登录自己 ...

  3. python列表简介

    什么是列表?如何使用列表?https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range 列表相关知识: ...

  4. 《并发编程的艺术》阅读笔记之Lock与AQS

    Lock接口 在jdk1.5之后,并发包下新增了一个lock接口,lock接口定义了锁的获取,锁的释放,等方法,需要用户手动设置.与关键字不同的是,lock具有可操作性,比如,可以中断线程,设置超时时 ...

  5. shiro:入门程序(一)

    SpringMVC项目 1:pom引入相关依赖 <dependencies> <!--测试依赖--> <dependency> <groupId>jun ...

  6. python 使用记录及问题

    编码问题 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 1: ordinal not in range(12 ...

  7. Java中的方法是什么以及方法的书写格式

    方法:完成特定功能的代码块注意:在很多语言里面有函数的定义,而在Java中函数被称为方法.方法格式:修饰符 返回值类型+ 方法名 (参数类型 参数名1,参数类型 参数名2...){方法体语句;retu ...

  8. 树莓派3b在rt-thread上移植LittlevGL

    树莓派3b在rt-thread上移植LittlevGL 目录 树莓派3b在rt-thread上移植LittlevGL 1.本文概述 2.资源准备 3.上手体验 4.rt-thread与lvgl进行无缝 ...

  9. tensorflow1.0 矩阵相乘

    import tensorflow as tf matrix1 = tf.constant([[3,3]]) matrix2 = tf.constant([[2],[2]]) product = tf ...

  10. curl请求本地域名问题

    curl在本地虚拟机上请求本地接口时候,出现域名解析问题,换为ip即可,可用curl_error() 或者curl_errno来调试: vue单个文件在引入时候自己的逻辑js文件一定要放在html后引 ...