A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3 measured in units where the width of the rectangles is 1.

 

Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.

Input

Input starts with an integer T (≤ 20), denoting the number of test cases.

Each case contains a line with an integer N (1 ≤ N ≤ 30000) denoting the number of rectangles. The next line contains Nspace separated positive integers (≤ 30000) denoting the heights.

Output

For each case, print the case number and the largest rectangle that can be made.

Sample Input

2

7

2 1 4 5 1 3 3

5

4 4 3 2 4

Sample Output

Case 1: 8

Case 2: 10

题意:有一系列的长条状的矩形,宽度都为1,相邻的竖立在x轴上,求最大的子矩形

胡扯:

有一回对我说道,“你学过算法么?”我略略点一点头。他说,“学过算法,……我便考你一考。XJOI的最大子矩形面积,怎样写的?”我想,AKIOI的人,怎么也来考我?便回过脸去,不再理会。孔乙己等了许久,很恳切的说道,“不能写罢?……我教给你,记着!这些算法应该记着。将来AKIOI的时候,秒题要用。”我暗想我和IOI的等级还很远呢,而且IOI也从不将这种题搬去;又好笑,又不耐烦,懒懒的答他道,“谁要你教,不是用单调栈胡搞毛搞么?”孔乙己显出极高兴的样子,将两个指头的长指甲敲着键盘,点头说,“对呀对呀!……最大子矩形面积有四样写法,你知道么?”我愈不耐烦了,努着嘴走远。孔乙己刚打开了c++,想在上面写代码,见我毫不热心,便又叹一口气,显出极惋惜的样子。

题解:

这题的确有四种解法

单调栈、笛卡尔树、类似kmp的解法、一种st表

嗯,后面两种我连名字都说不准确,所以还是不讲了

主要写两种常用的解法

首先是单调栈

单调栈就是一种栈内单调的数据结构,至于怎么维护,比如说一个单调递增的单调栈,你只需要在每加入一个数的时候,把所有比当前数大的栈顶全部弹掉就可以了

如果一个数被弹掉了,说明他能控制的矩形也已经到头了,所以就可以统计答案了,答案就是高度乘以(出去时间-进入时间)

然后唯一要注意的是该数的进入时间是第一个比他小的数的进入时间+1(他在栈中时下面的元素),而不是i,如果直接减的话就用进入时间就可以了

代码如下:

#include<stack>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; struct node
{
int time,val;
};
int n,a[],b[];
stack<node> s;
long long ans; int main()
{
scanf("%d",&n);
for(int i=; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(int i=; i<=n; i++)
{
int w=i;
while((!s.empty())&&s.top().val>a[i])
{
int ti=s.top().time;
w=ti;
int v=s.top().val;
ans=max(ans,1ll*(i-ti)*v);
s.pop();
}
s.push((node){w,a[i]});
}
while(!s.empty())
{
int ti=s.top().time;
int v=s.top().val;
ans=max(ans,1ll*(n-ti+)*v);
s.pop();
}
printf("%lld\n",ans);
}

然后是笛卡尔树

笛卡尔树的中序遍历就是原序列(二叉搜索树性质),而他的每个节点的值都保证是其子树中的极值(堆性质)

笛卡尔树是可以O(n)构建的

将点i先扔到i-1的儿子下,然后比较i-1的所有祖先,一直找到第一个值比a[i]小的祖先,把这颗祖先的右儿子改成他,把原来的右儿子改成他的左儿子

均摊分析复杂度是O(n)

建出了树可以直接用size*tr[i].num来算出最大子矩形面积

不过我是直接记录每个点的pos然后瞎搞的

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; struct node
{
int fa,ls,rs,num,pos;
}tr[];
int a[],n;
long long ans; void dfs(int pos,int l,int r)
{
if(l>r) return ;
ans=max(ans,1ll*(r-l+)*a[pos]);
dfs(tr[pos].ls,l,tr[pos].pos-);
dfs(tr[pos].rs,tr[pos].pos+,r);
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
tr[].num=;
tr[].rs=;
tr[].num=a[];
tr[].pos=;
for(int i=;i<=n;i++)
{
tr[i].num=a[i];
tr[i].pos=i;
int p;
for(p=i-;tr[i].num<tr[p].num;p=tr[p].fa);
tr[i].ls=tr[p].rs;
tr[p].rs=i;
tr[i].fa=p;
}
dfs(tr[].rs,,n);
printf("%lld\n",ans);
}

 

XJOI 3606 最大子矩形面积/LightOJ 1083 Histogram(单调栈/笛卡尔树)的更多相关文章

  1. 2019牛客暑期多校训练营(第二场)-H Second Large Rectangle(次大子矩阵,降维,直方图+单调栈)

    题目链接:https://ac.nowcoder.com/acm/contest/882/H 题目:给n×m的由01组成的矩阵,求次大全1子矩阵的大小. 思路:第一步还是降维操作,用a[i][j]记录 ...

  2. poj 2559 最大矩形面积(单调栈)

    题目:输入一个整数n,代表有n个  1(宽度) * h[i](高度)的矩形.接下来n个数依次给定一个矩形高度的高度h[i](i<=n). 求:在给定的依次排列的这堆矩形构成的图形里用一个矩形圈出 ...

  3. Vijos1055 奶牛浴场(极大化思想求最大子矩形)

    思路详见 王知昆<浅谈用极大化思想解决最大子矩形问题> 写得很详细(感谢~....) 因为不太会用递推,所以用了第一种方法,时间复杂度是O(n^2),n为枚举的点数,对付这题绰绰有余 思路 ...

  4. Histogram LightOJ - 1083

    Histogram LightOJ - 1083 题意:给出一个直方图,由n个长条组成,它们的x轴上坐标分别为1-n,读入n之后读入的一行中,第i个表示x轴上坐标为i的长条长度.求直方图最大的正方形面 ...

  5. [LeetCode] Rectangle Area 矩形面积

    Find the total area covered by two rectilinear rectangles in a2D plane. Each rectangle is defined by ...

  6. POJ 1151 Atlantis(线段树-扫描线,矩形面积并)

    题目链接:http://poj.org/problem?id=1151 题目大意:坐标轴上给你n个矩形, 问这n个矩形覆盖的面积 题目思路:矩形面积并. 代码如下: #include<stdio ...

  7. 25.按要求编写一个Java应用程序: (1)编写一个矩形类Rect,包含: 两个属性:矩形的宽width;矩形的高height。 两个构造方法: 1.一个带有两个参数的构造方法,用于将width和height属性初化; 2.一个不带参数的构造方法,将矩形初始化为宽和高都为10。 两个方法: 求矩形面积的方法area() 求矩形周长的方法perimeter() (2)通过继承Rect类编写一个具有

    package zhongqiuzuoye; //自己写的方法 public class Rect { public double width; public double height; Rect( ...

  8. 扫描线 + 线段树 : 求矩形面积的并 ---- hnu : 12884 Area Coverage

    Area Coverage Time Limit: 10000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit user ...

  9. 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)

    求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<c ...

随机推荐

  1. Fiddler监控面板显示ServerIP栏(Fiddler v5.0)

    Fiddler监控面板默认没有ServerIP这一栏,添加此栏方法如下: 1.点击Rules下的Customize Rules.js,会打开Fiddler ScriptEditor 2.在脚本中添加对 ...

  2. python学习——练习题(12)

    """ 题目:判断101-200之间有多少个素数,并输出所有素数. 质数(prime number)又称素数,有无限个. 质数定义为在大于1的自然数中,除了1和它本身以外 ...

  3. 跟我学算法-tensorflow 实现logistics 回归

    tensorflow每个变量封装了一个程序,需要通过sess.run 进行调用 接下来我们使用一下使用mnist数据,这是一个手写图像的数据,训练集是55000*28*28, 测试集10000* 28 ...

  4. Django 实现用户认证set_Cookie

    当用户通过认证时,set_Cookie(key, value) request.Cookie.get(key) 如果key不为空,就说明验证通过,否者重新跳转回login登录页面 对于URL urlp ...

  5. springboot整合最新版dubbo以及dubbo-admin的安装

    一.安装前准备 由于dubbo被阿里捐献给了apache,这次安装admin时,参考网上的资料,地址还是停留在之前的链接,踩了不少坑,这里记录下. dubbo-admin下载地址: 地址一:https ...

  6. README.md的编写

    1.编辑README文件 大标题(一级标题):在文本下面加等于号,那么上方的文字就变成了大标题,等于号的个数无限制,但一定要大于0 大标题 ==== 中标题(二级标题):在文本下面加下划线,那么上方的 ...

  7. 分别用js和css实现瀑布流

    下午查找了瀑布流的相关原理,找了一些css3实现的还有js实现的,最后总结了一些比较简单的,易懂的整理起来 1.css3实现 只要运用到    column-count分列 column-width固 ...

  8. Mysql 查询今天的某些时间之外的数据

    SELECT * FROM `attendancealert` WHERE DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(`AlertTime`)),'%Y-%m- ...

  9. 7-set用法详解

    C++中set用法详解 转载 http://blog.csdn.net/yas12345678/article/details/52601454 C++ / set 更详细见:http://www.c ...

  10. Linux常见问题及解决方案

    问题一: 删除Linux 的烦恼(没出现系统选择菜单只出现"grub": 问题描述: 安装了Linux.WinXP双系统,采用Grub引导系统.在XP下通过格式化磁盘(非法操作)删 ...