Triangle: The Data Structure(优秀の二维 ST 表)

link.
这种 RMQ 对像我这样萌新来说只有两种比较直观的方案:

  1. 线段树
  2. ST 表

首先考虑线段树,如果是朴素的一维线段树,那么我们只能一行一行地扫,显然相比暴力优化了一些,但不多,最终还是会愉快地 T 掉(亲测)。
然后我不会超冷门的数据结构二维线段树。
所以蒟蒻只能用好写的 ST 表了,只不过也是二维的。

开写!

首先观察一下样例(事实证明有时样例是很重要的),我们发现它并没有按照题目描述读入:

   1  2 3 4 5 6
7 8 9 0

实际上它是这么读的:

1
2 3
4 5 6
7 8 9 0

也就是说我们读入的和需要查询的其实都是一个等腰直角三角形。
那么我们按照惯用套路,设 \(st_{i,j,k}\) 表示以第 \(i\) 行第 \(j\) 列的点为上顶点的直角边长是 \(2^k\) 的三角形区域内的最大值,那么它的两条直角边分别是 \(i\rightarrow i+2^k-1\)\(j\rightarrow j+2^k-1\)
然后我们像平常一样再次发现了问题:
我们的普通二维 ST 表是针对矩形(准确来说应该是正方形)而言的,我们发现一个 \(st_{i,j,k}\) 的矩形可以恰好由 \(st_{i,j,k-1}\)\(st_{i,j+2^{k-1},k-1}\)\(st_{i+2^{k-1},j,k-1}\)\(st_{i+2^{k-1},j+2^{k-1},k-1}\) 四个已经算过的矩形构成,如图所示:

但是对于三角形来说我们可就没有这么幸运了:

我们发现一个 \(st_{i,j,k}\) 的等腰直角三角形无法由 \(st_{i,j,k-1}\)\(st_{i+2^{k-1},j,k-1}\)\(st_{i+2^{k-1},j+2^{k-1},k-1}\) 三个三角形契合起来,我们会留下中间一个灰色区域。
怎么办?我们尝试在原来的大三角形的底边正中间处再放置一个边长是 \(2^{k-1}\) 的三角形,这个三角形可以用 \(st_{i+2^{k-1},j+2^{k-2},k-1}\) 来表示(我标红的那一段正好是大三角形的底边长的 \(\frac{1}{4}\)):

但是好像还没有覆盖全?那就再在原三角形的另一条直角边和斜边的正中间再加一个吧!

此时我们就覆盖完全了,另外添加的那两个三角形可以用 \(st_{i+2^{k-2},j,k-1}\)\(st_{i+2^{k-2},j+2^{k-2},k-1}\) 表示。
不难证明 \(\forall \frac{n}{2}\le m<n\),一个边长是 \(n\) 的三角形都可以由不多于 \(6\) 个边长是 \(m\) 的三角形完全覆盖。
由于我们解决的是可重复贡献问题,我们直接用这 \(6\) 个三角形更新大的即可。
为了避免没用的循环,我们只需要枚举到满足 \(2^k\le h\) 的最大的 \(k\) 即可(\(h\) 是我们需要查询的边长)。
注意到需要查询的 \(h\) 是一定的,也就是 \(k\) 是一定的,因为你不这么干会 MLE,所以可以把 st 数组滚动起来,最后枚举 \(k\) 的维只开到 \(2\) 即可。
于是就有了预处理部分的代码:

read (n) ,read (h) ;
f (i ,1 ,n ,1) {f (j ,1 ,i ,1) {read (st[i][j][0]) ;}
}
for (int i = 0 ; ;i ++) {if (h >= (1 << i)) k = i ;else break ;
} // 找到最大的 k
f (t ,1 ,k ,1) {int u = t & 1 ,v = u ^ 1 ; // 分奇偶性讨论即可,注意奇数的上一个状态是偶数,反之亦然,那么 u 就是当前状态,v 是上一个状态f (i ,1 ,n - (1 << t) + 1 ,1) {f (j ,1 ,i ,1) {st[i][j][u] = max (st[i][j][v] ,max (st[i + (1 << t - 1)][j][v] ,st[i + (1 << t - 1)][j + (1 << t - 1)][v])) ;if (t > 1) { // <= 1 的时候没必要st[i][j][u] = max (st[i][j][u] ,max (st[i + (1 << t - 1)][j + (1 << t - 2)][v] ,max (st[i + (1 << t - 2)][j][v] ,st[i + (1 << t - 2)][j + (1 << t - 2)][v]))) ;}}} 
}

接下来就是查询部分,思路基本一致,但是注意到 \(h\) 不一定是 \(2\) 的正整数次幂,所以添加的三个三角形不再能直接表示为上面那样了,我们注意到我们添加的三个三角形都是在边的正中间的,那么我们来推到一下到底该怎么表示,以大三角形下面那个为例:

我们可以知道 \(1\) 号边减 \(2\) 号边等于 \(\frac{h-2^k}{2}\),由于我们作的是中垂线,那么 \(1\) 号减 \(2\) 号就等于 \(3\) 号减 \(4\) 号,得 \(5\) 号的长是 \(\frac{h-2^k}{2}\),也就是说我们添加的(红色的那个)三角形的顶点距离侧面的那条直角边的距离是 \(\frac{h-2^k}{2}\),那么它可以用 \(st_{i+h-1-2^k+1,j+\frac{h-2^k}{2},k-1}\) 来表示(\((i,j)\) 是大三角形的上顶点)。
同理可以得到其他两个三角形的表示。
那么我们的查询:

inline int query (int x ,int y) {int _ = x + h - 1 ,__ = y + h - 1 ;int u = k & 1 ; // 求出 k 对应的第三为下标int ans = max (st[x][y][u] ,max (st[_ - (1 << k) + 1][y][u] ,st[_ - (1 << k) + 1][__ - (1 << k) + 1][u])) ; // 正常的 ST 表查询操作if (k <= 1) return ans ; // 没必要在加那三个三角形了int t = (h - (1 << k)) >> 1 ;ans = max (ans ,max (st[_ - (1 << k) + 1][y + t][u] ,max (st[x + t][y][u] ,st[x + t][y + t][u]))) ; // 就是上面我说的那个return ans ;
} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/787170.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python3.11二进制AI项目程序打包为苹果Mac App(DMG)-应用程序pyinstaller制作流程(AppleSilicon)

众所周知,苹果MacOs系统虽然贵为Unix内核系统,但由于系统不支持N卡,所以如果想在本地跑AI项目,还需要对相关的AI模块进行定制化操作,本次我们演示一下如何将基于Python3.11的AI项目程序打包为MacOS可以直接运行的DMG安装包,可以苹果系统中一键运行AI项目。 MacOs本地部署…

2.MapReduce论文总结

一. 介绍很多业务逻辑很简单,主要难点是数据量太大,可使用分布式处理提高速度。 传统分布式程序,计算逻辑和分布式任务分发、故障恢复混在一起,原本简单的计算逻辑变得模糊不清,难以处理。 MapReduce将两者分离,任务分发,容错,恢复等逻辑由模型完成,程序员只需要专注计…

Lab1 记录

一、非并行版本分析 1.非并行版本MapReduce流程通过第一个参数,传入Map和Reduce 函数 之后的参数为待处理文件名 读取文件 调用Map函数,对文件内容进行处理,生成KV对 对KV对进行sort 按照Key进行分组,然后对每组数据调用Reduce 将结果写入文件二、Lab思路 概述:Worker向Co…

JMeter:性能测试利器全解析

目录JMeter:性能测试利器全解析一、JMeter 的基础概念(一)什么是 JMeter(二)主要功能特点二、使用 JMeter 测试 Web 应用的步骤(一)安装与启动(二)创建测试计划(三)配置 Web 应用测试场景(四)运行测试(五)分析测试结果三、案例分析(一)案例背景(二)测试步骤…

ZBlogPHP迁移网站错误提示:Permission denied(请确保你的网站有写入权限777)

解决方案:设置你的网站目录为777 写入权限即可【注意:如果755可能会不行,最好直接使用777搞定】扫码添加技术【解决问题】专注中小企业网站建设、网站安全12年。熟悉各种CMS,精通PHP+MYSQL、HTML5、CSS3、Javascript等。承接:企业仿站、网站修改、网站改版、BUG修复、问题…

zblog网站提示MySQL数据库无法连接

前天搭建好的博客网站,在睡了一觉之后,网站竟然出现故障无法正常运行了,在此期间,没有进行任何的操作。就连主页都无法进入,页面一直提示“MySQL 数据库无法连接”。不管怎样刷新页面,还是重启服务器,都毫无作用。 最终,从中午 1 点一直忙活到凌晨 2 点,还好皇天不负有…

20-学习卷积核

import torch import torch.nn as nnX = torch.rand((6, 8)) Y = torch.rand((6, 7))# (批量⼤⼩、通道、⾼度、宽度) X = X.reshape((1, 1, 6, 8)) Y = Y.reshape((1, 1, 6, 7)) lr = 3e-2# 构造卷积层 PyTorch 会使用默认的初始化方法,例如 Xavier 初始化或 Kaim 初始化…

这下罄竹难书了

/ /由四个金牌命制的联赛模拟试卷,使我校高二高三竞赛班取得了一试最高 84 分,加试最高 160 分的好成绩! 一试 一、填空题如图是一个 \(4\times 4\) 的正方形方格表,则最少需要 \(\text{_____}\) 条直线,才能使得每个方格都被至少一条直线穿过。设复数 \(z\) 满足:\(\fra…

解决Z-blog数据库链接错误?

你是否也曾遇到过在登录 Z-blog 博客时,系统显示“错误原因: 数据库连接错误”这样的状况呢?频繁出现此种情况对于 SEO 优化而言是极为不利的。那么,究竟应当如何解决 Z-blog 数据库链接错误的问题呢?首先,我们得深入剖析为何会产生这样的状况,其原因主要有两点。不管是…

Java中stream的详细用法

原文地址:https://www.cnblogs.com/Ao0216/p/15319553.html 一、概述 Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询…

zblogphp的错误提示分为“错误原因”和“文件位置”两个部分

zblogphp 的错误提示主要划分为“错误原因”以及“文件位置”这两个部分。 就“错误原因”而言,其通常是由一系列的专业术语所构成的,对于不熟悉 php 的人来说,可能难以理解。 但别担心,您可以将其复制下来,然后使用百度翻译之类的工具进行翻译,说不定运气好的话能大概弄…

zblogphp错误之“未知方法或属性 (set_error_handler)“解决办法

zblogphp 程序中出现的一个错误。错误信息为“(512)E_USER_WARNING : 未知方法或属性 (set_error_handler) (1.5.1.1740 (Zero)) (Linux; Apache; PHP 5.2.17; mysqli; curl)”。产生该错误的原因通常是用户对 zblogphp 程序进行了升级,从 1.4 到 1.5 版本修改了部分函数名称,…