ABC366D 题解

news/2024/9/20 15:43:59/文章来源:https://www.cnblogs.com/Xiang-he/p/18355037

第一眼是想写 \(kd-tree\) 的。

然后发现这就是一道三维前缀和的板子题。

三维前缀和

要想学习三维前缀和,我们首先得了解前缀和的概念,并且学会一维、二维前缀和。

什么是前缀和

前缀和是容斥原理的典型应用。这种优化方式可以使求和操作的时间复杂度降低到 \(O(1)\)(但是需要提前预处理)。

一维前缀和 & 二维前缀和

对于一维的一个序列 \(a_i\),如果我们有很多询问,每次询问让你求一个区间 \([l,r]\) 的和,我们就可以使用一维前缀和来优化。

具体地,我们设前缀序列 \(g_i = g_{i-1} + a_i\),那么不难发现,区间 \([l, r]\) 的和就是 \(g_r - g_{l - 1}\)

对于一个二维的序列同理,我们设 \(g_{i,j} = g_{i-1,j} + g_{i,j-1} - g_{i-1,j-1} + a_{i,j}\),就可以求出任意部分的和。

一维前缀和&二维前缀和

在一维序列中,红色部分的和就是黑色部分的和减掉绿色部分的和。那么前缀和的公式就是

在二维序列中,红色部分的和就是黑色部分的和减掉绿色部分的和,然后再加上黄色部分的和(因为黄色部分被减了 \(2\) 次)。

三维前缀和

三维前缀和同理,那么下面给出三维前缀和的图。

三维前缀和

可以发现...这完全看不懂啊!

没关系,我们将它拆开研究。

我们可以看到,黑色部分包括了要求的红色部分。那么我们就可以用黑色部分减掉剩余的部分,然后求出红色部分。

我们需要减掉这三个绿色部分:

减1

减2

减3

但是这时候又会发现一个问题,绿色部分的交(如图)被重复减了。

减交

所以我们需要找到绿色部分两两的交,并且加回来。即下图的黄色部分

加1

加2

加3

这时候,我们发现还是不对,黄色部分也有交!

加交

那么我们还需要将黄色部分的交(即下图粉色部分)再减掉。

减4

那么反过来,我们也可以推出前缀和的公式:

\[g_{i,j,k} = g_{i-1,j,k}+g_{i,j-1,k}+g_{i,j,k-1}\\-g_{i-1,j-1,k}-g_{i-1,j,k-1}-g_{i,j-1,j-1}\\+g_{i-1,j-1,k-1}+a_{i,j,k} \]


然后我们来看题。

可以发现这玩意就是一道三维前缀和的板子题,非常简单。

\(prefix[x][y][z]\) 为从 \((1,1,1)\)\((x,y,z)\) 的区域的前缀和,我们需要查询从 \((Lx, Ly, Lz)\)\((Rx, Ry, Rz)\) 的子立方体的和,公式为:

\[[ \text{Sum} = \text{prefix}[Rx][Ry][Rz] ] \]

\[[ - \left( Lx > 1 ? \text{prefix}[Lx-1][Ry][Rz] : 0 \right) ] \]

\[[ - \left( Ly > 1 ? \text{prefix}[Rx][Ly-1][Rz] : 0 \right) ] \]

\[[ - \left( Lz > 1 ? \text{prefix}[Rx][Ry][Lz-1] : 0 \right) ] \]

\[[ + \left( Lx > 1 \text{ and } Ly > 1 ? \text{prefix}[Lx-1][Ly-1][Rz] : 0 \right) ] \]

\[[ + \left( Lx > 1 \text{ and } Lz > 1 ? \text{prefix}[Lx-1][Ry][Lz-1] : 0 \right) ] \]

\[[ + \left( Ly > 1 \text{ and } Lz > 1 ? \text{prefix}[Rx][Ly-1][Lz-1] : 0 \right) ] \]

\[[ - \left( Lx > 1 \text{ and } Ly > 1 \text{ and } Lz > 1 ? \text{prefix}[Lx-1][Ly-1][Lz-1] : 0 \right) ] \]


prefix[Rx][Ry][Rz] 是查询区域的总和的基础。

减去 \((Lx-1)\) 平面上的部分,表示区域中不包括 \(Lx\) 之前的部分。

减去 \((Ly-1)\) 平面上的部分,表示区域中不包括 \(Ly\) 之前的部分。

减去 \((Lz-1)\) 平面上的部分,表示区域中不包括 Lz 之前的部分。

加上 \((Lx-1, Ly-1)\) 立方体的部分,因为这个区域被多次减去了。

加上 \((Lx-1, Lz-1)\) 立方体的部分,因为这个区域被多次减去了。

加上 \((Ly-1, Lz-1)\) 立方体的部分,因为这个区域被多次减去了。

减去 \((Lx-1, Ly-1, Lz-1)\) 立方体的部分,因为这个区域被多次加回来了。

code


#include "bits/stdc++.h"using namespace std;const int MAXN = 100; int A[MAXN+1][MAXN+1][MAXN+1];int prefix[MAXN+1][MAXN+1][MAXN+1];int main() {int n, q;cin >> n ;// 读取三维数组数据for (int x = 1; x <= n; ++x) {for (int y = 1; y <= n; ++y) {for (int z = 1; z <= n; ++z) {cin >> A[x][y][z];}}}// 计算三维前缀和for (int x = 1; x <= n; ++x) {for (int y = 1; y <= n; ++y) {for (int z = 1; z <= n; ++z) {prefix[x][y][z] = A[x][y][z]+ (x > 1 ? prefix[x-1][y][z] : 0)+ (y > 1 ? prefix[x][y-1][z] : 0)+ (z > 1 ? prefix[x][y][z-1] : 0)- (x > 1 && y > 1 ? prefix[x-1][y-1][z] : 0)- (x > 1 && z > 1 ? prefix[x-1][y][z-1] : 0)- (y > 1 && z > 1 ? prefix[x][y-1][z-1] : 0)+ (x > 1 && y > 1 && z > 1 ? prefix[x-1][y-1][z-1] : 0);}}}cin >> q;while (q--) {int Lx, Rx, Ly, Ry, Lz, Rz;cin >> Lx >> Rx >> Ly >> Ry >> Lz >> Rz;// 前缀和查询范围内的和int result = prefix[Rx][Ry][Rz]- (Lx > 1 ? prefix[Lx-1][Ry][Rz] : 0)- (Ly > 1 ? prefix[Rx][Ly-1][Rz] : 0)- (Lz > 1 ? prefix[Rx][Ry][Lz-1] : 0)+ (Lx > 1 && Ly > 1 ? prefix[Lx-1][Ly-1][Rz] : 0)+ (Lx > 1 && Lz > 1 ? prefix[Lx-1][Ry][Lz-1] : 0)+ (Ly > 1 && Lz > 1 ? prefix[Rx][Ly-1][Lz-1] : 0)- (Lx > 1 && Ly > 1 && Lz > 1 ? prefix[Lx-1][Ly-1][Lz-1] : 0);cout << result << endl;}return 0;
}

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

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

相关文章

C# 如何防止WinForm程序多次运行

[C# 开发技巧]如何防止程序多次运行 - Learning hard - 博客园 (cnblogs.com) 一、引言 最近发现很多人在论坛中问到如何防止程序被多次运行的问题的,如: http://social.msdn.microsoft.com/Forums/zh-CN/6398fb10-ecc2-4c03-ab25-d03544f5fcc9, 所以这里就记录下来,希望给遇到…

lwIP——带操作系统(FreeRTOS)移植

1. lwIP前期准备 在程序工程中,我们在工程文件夹下创建了一个名为 “lwip”的子文件夹。在“lwip”文件夹下,我们又创建了一个子文件夹:arch 。arch 文件夹用于存放 lwIP 系统的配置文件;2. 添加lwIP源文件3. 添加网卡驱动程序/* Includes -------------------------------…

Less is richness,基于less is more的博客园宽屏主题魔改

写在前面 之前做过很多个人博客,都是做着玩的,资源托管在免费或低价的服务器上,也不经常维护,所以就一直不长久,最终还是选择了博客园。发现博客园可以自定义样式,于是试着给博客换了一个又一个主题。个人比较喜欢宽屏的样式,感觉LessIsMore主题布局比较好、也比较简洁,…

5 大场景上手通义灵码企业知识库 RAG

大家好,我是通义灵码,你的智能编程助手!最近我又升级啦,智能问答功能全面升级至 Qwen2,新版本在各个方面的性能和准确性都得到了显著提升。此外,行间代码补全效果也全面优化,多种编程语言生成性能及准确性大幅提升,如前端、Java、Go、Python、C++ 等。此外,灵码新增代…

2024 年了,IT 运维监控系统都有哪些推荐?

大浪淘沙,2024 年的今天,市面上很多监控系统慢慢淡出了大家的视野,而一些新的监控系统也逐渐崭露头角。今天我们就来看看 2024 年的当下,哪些 IT 运维监控系统最值得关注。 Prometheus毫无疑问,Prometheus 是最值得关注的监控系统,因为 Prometheus 的规范和生态都非常厉害…

不只是前端,后端、产品和测试也需要了解的浏览器知识(二)

继上篇《 不只是前端,后端、产品和测试也需要了解的浏览器知识(一)》介绍了浏览器的基本情况、发展历史以及市场占有率。 本篇文章将介绍浏览器基本原理。在掌握基本原理后,通过技术深入,在研发过程中不断创新,推动产品性能、用户体验的提升,来实现业务的增长,创造可持…

三十分钟入门基础Go(Java小子版)

前言 Go语言定义 Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态、强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC,结构形态及 CSP-style 并发计算。 适用范围 本篇文章适用于学习过其他面向对象语言(Java、…

(二) 树莓派CM4调试

1. 参考资料资料汇总页面https://shumeipai.nxez.com/raspberry-pi-datasheets《bcm2711-peripherals.pdf》,下载地址https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf《cm4io-datasheet.pdf》,下载地址https://datasheets.raspberrypi.com/cm4/cm4-data…

中国式报表有这么多种类型,你都知道吗?

中国式报表是一种在中国企业中使用的会计报告格式,但你真的了解它吗?你知道它有多少种类型吗?今天我们就一起来聊聊,中国式报表都包含哪些类型的报表吧!按样式来划分,中国式报表通常分为以下几类:1. 行式报表 行式报表也就是我们常说的清单式明细表,是最常见也是最简单…

JDBC加载MySQL驱动【底层实现】

JDBC4.0如何加载引入依赖<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.32</version></dependency>上代码import java.sql.Connection;import java.sql.DriverManager;imp…

tensorboard_logger库无法导入的问题解决

一、问题描述最近在学习深度学习时,从大神们那里copy的代码中有用到tensorboard_logger这个库的东西,所以很自然地就用conda install或者pip去安装它,但是结果是:python开源库里面没有这东西。 这就让我很苦恼,所以只能自己动手,丰衣足食了。 二、解决方法首先找到tenso…

sqlserver 2000 数据库文件*。mdf附加到sql2008 报错 提示使用dbcc checkcatalog检查

sqlserver 2000 数据库文件*。mdf附加到sql2008 报错 提示使用dbcc checkcatalog检查检查提示有两个存储过程对象 在 SYSOBJECTS 与 SYSCOMMENTS 之间不匹配。drop procedure TS_G_ArApIniModiy drop procedure TS_T_CRMContactionQry 删除这两个存储过程之后可以直接在sqlser…