【2020.11.30提高组模拟】柱形图(histogram) 题解

题意简述

有\(n\)个长方体并排这样放着,每种颜色的长方体的宽度都为\(1\),高\(a_i\)长\(b_i\)。

求在这些长方体内部最大能够放入的长方体的体积。

\(n\le200000\).

Solution

这个问题可以在\(O(n\log^2n)\)的时间复杂度内解决。

设\(f(i,j)=\min(a_i,\dots,a_j),g(i,j)=\min(b_i,\dots,b_j)\)。

这个问题就被转化成了找到一个区间\([i,j]\)使得\(\max f(i,j)\cdot g(i,j)\cdot (j-i+1)\)。

考虑分治\((divide-and-conquer)\)。

\(solve(lo,hi)\)将找到区间\([lo,hi]\)中横跨区间\(mid\)的最优的区间。他将递归调用\(solve(lo,mid-1)\)和\(solve(mid+1,hi)\)。

为了递归合并区间,我们设\([l,r]\)是一个\(l\in[lo,mid],r\in[mid,hi]\)的区间。我们考虑四种情况:

  1. \(f(l,r)\)和\(g(l,r)\)都是由左半部分决定,即\(f(l,r)=f(l,mid),g(l,r)=g(l,mid)\).
  2. \(f(l,r)\)和\(g(l,r)\)都取决于右半边,即\(f(l,r)=f(mid,r),g(l,r)=g(mid,r)\).
  3. \(f(l,r)\)取决于左侧,\(g(l,r)\)取决于右侧.
  4. \(f(l,r)\)取决于右侧,\(g(l,r)\)取决于左侧.

情况\(1/2\)是类似的,情况\(3/4\)是类似的,所以我们只需要考虑情况\(1/3\)。

情况\(1\)

\(f(l,r)\)和\(g(l,r)\)都是由左半部分决定

注意到这意味着\(f(l,mid)\le f(mid,r),g(l,mid)\le g(mid,r)\).

我们可以使用双指针法在\(O(hi-lo)\)的时间内解出来,所以总时间复杂度就变成了\(O(n\log n)\).

情况\(3\)

\(f(l,r)\)取决于左侧,\(g(l,r)\)取决于右侧

注意到这意味着\(f(l,mid)\le f(mid,r),g(l,mid)\le g(mid,r)\).

这个就没有情况\(1/2\)那样可以在\(O(n\log n)\)内解出来。

它存在\(O(n\log^2n)\)的解法,我们将首先介绍一种\(O(n\log^3n)\)的解法。

\[\begin{aligned}
f(l,r)\cdot g(l,r)\cdot (r-l+1)&=f(l,mid)\cdot g(mid,r)\cdot (r-l+1)\\
&=f(l,mid)\cdot (-l+1)\cdot g(mid,r)+f(l,mid)\cdot g(mid,r)\cdot r\\
&=\langle(f(l,mid)\cdot (-l+1),f(l,mid)),(g(mid,r),g(mid,r)\cdot r)\rangle
\end{aligned}
\]

其中\(\langle(a,b),(c,d)\rangle\)表示向量\((a,b)\)和\((c,d)\)的点积。

注意到第一个向量仅仅依赖于\(l\),第二个向量仅仅依赖于\(r\).

对于一个固定的\(l\),我们希望找到一个\(r\in[a(l),b(l)]\)使得这两个向量的点积最大。如果\(r\)不属于那个区间, 我们可以计算第二个点集的凸包,然后用三分查找找到对于每个\(l\)的最优的\(r\)。但是现在,我们可以对这些点按照它们的横坐标排序,然后建一棵线段树,这棵线段树的每个节点都记录着相应的凸包。所以对于每个\(l\)我们将会查看线段树上的\(O(\log n)\)个节点,然后以单次 的时间在每个节点对应的凸包内做三分查找。 这给我们带来了一个\(O(n\log^3n)\)的算法,因为我们需要再用一个分治统计答案。

现在我们想要摆脱二分,注意到点\(f(l,mid)\cdot (-l+1,1)\)随着\(l\)增加而向逆时针移动,所以凸包上的极值点 也会向逆时针移动,对于线段树上的每个节点,我们可以在\(O(n)\)的时间内完成一次询问,通多记录上次询问的极值点的指针的方式。这给我们带来了一个\(O(n\log^2n)\)的方法。

【2020.11.30提高组模拟】柱形图(histogram) 题解翻译的更多相关文章

  1. 【2020.11.30提高组模拟】剪辣椒(chilli)

    剪辣椒(chilli) 题目描述 在花园里劳累了一上午之后,你决定用自己种的干辣椒奖励自己. 你有n个辣椒,这些辣椒用n-1条绳子连接在一起,任意两个辣椒通过用若干个绳子相连,即形成一棵树. 你决定分 ...

  2. 【2020.11.30提高组模拟】删边(delete)

    删边(delete) 题目 题目描述 给你一棵n个结点的树,每个结点有一个权值,删除一条边的费用为该边连接的两个子树中结点权值最大值之和.现要删除树中的所有边,删除边的顺序可以任意设定,请计算出所有方 ...

  3. JZOJ 【2020.11.30提高组模拟】剪辣椒(chilli)

    题目大意 给出一棵 \(n\) 个节点的树,删去其中两条边 使得分出的三个子树大小中最大与最小的差最小 分析 先一边 \(dfs\) 预处理出以 \(1\) 为根每个点的 \(size\) 然后按 \ ...

  4. 【2020.11.28提高组模拟】T1染色(color)

    [2020.11.28提高组模拟]T1染色(color) 题目 题目描述 给定 \(n\),你现在需要给整数 \(1\) 到 \(n\) 进行染色,使得对于所有的 \(1\leq i<j\leq ...

  5. 【2020.11.28提高组模拟】T2 序列(array)

    序列(array) 题目描述 ​给定一个长为 \(m\) 的序列 \(a\). 有一个长为 \(m\) 的序列 \(b\),需满足 \(0\leq b_i \leq n\),\(\sum_{i=1}^ ...

  6. JZOJ 6904. 【2020.11.28提高组模拟】T3 树上询问(query)

    题目 你有一棵 \(n\) 节点的树 ,回答 \(m\) 个询问,每次询问给你两个整数 \(l,r\) ,问存在多少个整数 \(k\) 使得从 \(l\) 沿着 \(l \to r\) 的简单路径走 ...

  7. 【2020.12.03提高组模拟】A组反思

    估计:40+10+0+0=50 实际:40+10+0+0=50 rank40 T1 赛时看到\(n,m\leq9\),我当机立断决定打表,暴力打了几个点之后发现在\(n\ne m\)且\(k\ne0\ ...

  8. 11.5NOIP2018提高组模拟题

    书信(letter) Description 有 n 个小朋友, 编号为 1 到 n, 他们每人写了一封信, 放到了一个信箱里, 接下来每个人从中抽取一封书信. 显然, 这样一共有 n!种拿到书信的情 ...

  9. 【2020.12.01提高组模拟】卡特兰数(catalan)

    题目 题目描述 今天,接触信息学不久的小\(A\)刚刚学习了卡特兰数. 卡特兰数的一个经典定义是,将\(n\)个数依次入栈,合法的出栈序列个数. 小\(A\)觉得这样的情况太平凡了.于是,他给出了\( ...

  10. 【2020.12.01提高组模拟】A组反思

    105,rk45 T1 赛时一开始先打了\(m=0\)的情况,也就是普通的卡特兰数,然后打了暴力,样例过了,把样例改改就不行了,原因没有保证是枚举的是合法的出栈序列 得分:\(WA\&TLE1 ...

随机推荐

  1. [tldr]通过指令获取github仓库的单个文件的内容

    针对一个公开的github仓库,有些时候不需要clone整个仓库的内容,只需要对应的几个文件.但是直接通过网页点击下载文件很麻烦,在服务器上也不好这样操作. 因此,如何使用curl或者wget指令快速 ...

  2. nuxt,从开发到线上部署

    起因: 前段时间,同组小伙伴使用vue做了一个小后台,使一位后端沉寂多年得求道之心又躁动了起来...然后,当我和这个躁动起来得后端要合作重构一个网站得时候,后端小哥哥说,就知道套页面,套页面,不用新技 ...

  3. docker login harbor x509: certificate signed by unknown authority

    前言 docker login harbor x509: certificate signed by unknown authority 解决 打开 /etc/docker/daemon.json,如 ...

  4. linux安装protoc

    protobuf 是做什么的? 专业的解答: Protocol Buffers 是一种轻便高效的结构化数据存储格式,可用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式.它可用于通讯协议. ...

  5. Ansible运行临时命令

    一.基本语法格式: 格式:ansible 受控主机IP/主机组 [选项] 参数 选项 -k 手动输入SSH协议的代码 -l 指定主机清单文件 -m 指定要使用的模块名 -a 设置传递给模块的参数 -M ...

  6. Docker管理面板系列——Portainer

    一.介绍 Portainer是个轻量级的Docker管理面板,和Rancher这种重量级选手没法比,Portainer倾向于单机的管理(后来发现能够添加多个单机节点切换着管理),当然,在Docker搞 ...

  7. 【Linux】U-Boot 加载并启动 Linux 系统程序

    U-Boot 加载并启动 Linux 系统程序 零.介绍 最近在玩一些嵌入式的开发板,在引导操作系统时需要用到U-Boot,故此研究一下. U-Boot(Universal Bootloader)是一 ...

  8. 【教程】Anaconda安装

    零.Anaconda介绍 Anaconda个人版是一个免费.易于安装的包管理器.环境管理器和Python发行版(所以装了Anaconda就可以不用再另外装Python了),有提供非常多的开源包,用An ...

  9. 新装ubuntu电脑的一些调整

    必要命令的安装 必要开发工具的安装 更换国内软件源 /etc/apt/sources.list文件,后面添加下面地址用来添加阿里源 deb http://mirrors.aliyun.com/ubun ...

  10. RAGflow搭建text-to-sql的AI研发助手

    一.概述 text-to-sql 技术允许用户通过自然语言提问,系统自动将其转换为 SQL 语句并执行,大大降低了数据查询的门槛,提高了工作效率. text-to-sql 技术在数据分析.智能客服.数 ...