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. Idea2016远程调试Java项目

    一.在IDEA中配置远程tomcat 1.打开配置页面 选择"+" → "Tomcat Server" → "Remote" 填写名称和目标 ...

  2. Julia - 字符串判断函数

    isascii() 判断是否是 ascii 码,返回 Bool 值 julia> isascii('a') true julia> isascii('α') false julia> ...

  3. 一些通用的触发移动App崩溃的测试场景

    一些通用的触发移动App崩溃的测试场景,如下: 1 验证在有不同的屏幕分辨率,操作系统和运营商的多个设备上的App行为. 2 用新发布的操作系统版本验证App的行为. 3 验证在如隧道,电梯等网络质量 ...

  4. springmvc 使用ajx上传文件 不设置form enctype

    最近在做一个小项目 碰到这个问题 解决方案如下 1.js代码如下 获取当前form 转换为formdata ajax提交到后台 var form = $("#importForm" ...

  5. 03-23 MVC框架(以查询、删除为例)

    1.MVC的定义: MVC(Model-View-Controller,模型-视图-控制器)是用于将应用程序粉好吃呢过如下3个主要方面的体系结构模式: 模型(Model):一组类和业务规则,类用于描述 ...

  6. 更改AD域安全策略-密码必须符合复杂性要求

    在域环境中,修改域用户密码时,会提示不符合密码策略, 更改"本地安全策略"是不会对域产生任何的作用的. 上图中可以看,这里按钮都是灰色的! 下面这个步骤教你如何找到"域安 ...

  7. 打开当前目录的其他exe

    STARTUPINFO si; PROCESS_INFORMATION pi; memset(&si, , sizeof(si)); si.cb = sizeof(STARTUPINFO); ...

  8. jquery中ready函数,$(function(){})与自执行函数的区别

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  9. 前端开发之JavaScript基础篇二

    主要内容: 1.流程控制条件语句和switch语句 2.for循环和while循环 3.Break语句和Continue语句 4.数组和数组常用方法 5.函数 6.对象 一.流程控制条件语句和swit ...

  10. Nginx负载均衡高可用

    1.   Nginx负载均衡高可用 首先介绍一下Keepalived,它是一个高性能的服务器高可用或热备解决方案,Keepalived主要来防止服务器单点故障的发生问题,可以通过其与Nginx的配合实 ...