P6818 [PA2013]Działka 题解

P6818 [PA2013]Działka

前言

我太菜了。。。。

对着 jiangly 大佬的题解研究了一下午研究了一下午才搞出来(泪目。

作为一个蒟蒻,我就详细的讲一下我对与本题的理解。

题意

本题的的题意描述的还是比较明了。

在二维坐标系中,输入 \(n\) 个点 \(m\) 次询问,

每次询问,给出一个矩阵,

求出矩阵内极大凸包的面积。

题解

1.如何求面积

二维平面的计算几何题,较常见的做法就是利用叉积。本题亦如此。

叉积有个优美的性质,我们可以发现对于 \(\vec{a} \times \vec{b}\) 可以在二维平面赋予特殊意义( \(S\) 为三角形面积)。

\(\vec{a} \times \vec{b} = 2S\)

利用这个性质我们就可以求出任意凸包的面积。

举个例子,\(4\) 个点坐标为 \((1 , 1) (1 , 3) (3 , 3) (3 , 1)\) 在此记为 \(0\) 号点到 \(3\) 号点,\(G\) 记为原点,

那要求出其凸包的面积就可以写作:

\({ \vec{G0} \times \vec{G3} + \vec{G3} \times \vec{G2} + \vec{G1} \times \vec{G0} + \vec{G1} \times \vec{G0} \over 2}\)

P6818 [PA2013]Działka 题解

其实就可以理解为绿色的三角形相加。

P6818 [PA2013]Działka 题解

再容斥一下减去红色三角(由于叉乘的顺寻原因出来的红色三角形负数)。

P6818 [PA2013]Działka 题解

剩下的就是索要求的凸包面积。

因为本题 \(n \le 3000\) 我们可以考虑直接 \(O(n ^ 2)\) 预处理出每两个向量的叉乘(其实不是任意两个的叉乘,详见第三部分)。

呢么下面的任务就是快速找到凸包外面的点。


2.如何找凸包

如何找凸包呢?有一个十分优雅的方法。可以考虑寻找类似于四分之一扇形的凸包,然后每次旋转找到 \(4\) 个半圆再求和。假设我们先找右上角的扇形。

对于如下图形如何优美的找到凸包呢?

P6818 [PA2013]Działka 题解

我们可以考虑将点以优先 \(x\) 从大到小后 \(y\) 从大到小的顺序找(过程可以顺便预处理前面提到的任意两点的距离)。

手模一下发现,我们先会从 \(1\) 号点就可以轻易的找到 \({1 , 3 , 4}\) 的点集。

呢如何记录高效的记录答案呢?


3.如何记录答案

直接枚举每个问题,显然会 T 飞。

考虑在记录两点间距离的时候直接记录最外面凸包的距离,例如前面的图片,在记录 \(\vec{1} \times \vec{4}\) 的时可以直接记录为 \(\vec{1} \times \vec{3} + \vec{3} \times \vec{4}\)。样我们在统计答案的时候实际上只需要记录只需要记录他最接近边界的两个点就可了。

考虑每一次记录答考虑使用线段树加扫描线的思想,如下图为每个点。

P6818 [PA2013]Działka 题解

当我们更新完最外面的橙色的点还没有处理蓝色的点的时候,考虑有哪些区间里的提问是可以被更新的。

P6818 [PA2013]Działka 题解

黄色的区间是可以被更新的,利用扫描线的思想做到 \(O(m \log m)\) 维护每个图形的边界。


\(\bullet\) 加强版

模拟赛出了这道题的加强版,若坐标的范围改成 \(-10^7 \le x ,y \le 10^7\)

两个办法,一是使用效率更高的 zkw 线段树,二是数据离散化。

当然本题用普通线段树就可以切了。

Code

代码跟 jiangly 大佬的没有本质区别,就不粘了(doge去翻上一篇题解吧。

原文链接:https://www.cnblogs.com/xztx666/p/17363914.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:P6818 [PA2013]Działka 题解 - Python技术站

(0)
上一篇 2023年4月30日
下一篇 2023年4月30日

相关文章

  • 驱动开发:通过MDL映射实现多次通信

    在前几篇文章中LyShark通过多种方式实现了驱动程序与应用层之间的通信,这其中就包括了通过运用SystemBuf缓冲区通信,运用ReadFile读写通信,运用PIPE管道通信,以及运用ASYNC反向通信,这些通信方式在应对一收一发模式的时候效率极高,但往往我们需要实现一次性吐出多种数据,例如ARK工具中当我们枚举内核模块时,往往应用层例程中可以返回几条甚至…

    C++ 2023年4月30日
    00
  • 玩一玩 Ubuntu 下的 VSCode 编程

    一:背景 1. 讲故事 今天是五一的最后一天,想着长期都在 Windows 平台上做开发,准备今天换到 Ubuntu 系统上体验下,主要是想学习下 AT&T 风格的汇编,这里 Visual Studio 肯定是装不了了,还得上 VSCode,刚好前几天买了一个小工控机,这里简单记录下 零到一 的过程吧。 二:搭建一览 1. VSCode 安装 在 U…

    C++ 2023年5月3日
    00
  • <五>move移动语义和forward类型转发

    move : 移动语义,得到右值类型forward:类型转发,能够识别左值和右值类型 只有两种形式的引用,左值引用和右值引用,万能引用不是一种引用类型,它存在于模板的引用折叠情况,但是能够接受左值和右值区分左值和右值得一个简单方式就是能不能取地址一个右值一旦有名字那么就变成了左值 #include <iostream> using namespa…

    C++ 2023年5月4日
    00
  • 【Visual Leak Detector】核心源码剖析(VLD 1.0)

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇对 VLD 1.0 源码做内存泄漏检测的思路进行剖析。同系列文章目录可见 《内存泄漏检测工具》目录 目录 说明 1. 源码获取 2. 源码文件概览 3. 源码剖析 3.1 注册自定义 AllocHook 函数 3.2 存储调用堆栈信息 3.3 生成泄漏检测报告 4. 其他问题 4.1 如何区分…

    C++ 2023年4月27日
    00
  • 驱动开发:内核使用IO/DPC定时器

    本章将继续探索驱动开发中的基础部分,定时器在内核中同样很常用,在内核中定时器可以使用两种,即IO定时器,以及DPC定时器,一般来说IO定时器是DDK中提供的一种,该定时器可以为间隔为N秒做定时,但如果要实现毫秒级别间隔,微秒级别间隔,就需要用到DPC定时器,如果是秒级定时其两者基本上无任何差异,本章将简单介绍IO/DPC这两种定时器的使用技巧。 首先来看IO…

    C++ 2023年4月18日
    00
  • 【Visual Leak Detector】配置项 ForceIncludeModules

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍 VLD 配置文件中配置项 ForceIncludeModules 的使用方法。 同系列文章目录可见 《内存泄漏检测工具》目录 目录 说明 1. 配置文件使用说明 2. 设置需要检测的第三方模块 2.1 测试代码 2.2 ForceIncludeModules 为空时的输出 2.3 For…

    C++ 2023年4月18日
    00
  • 【Visual Leak Detector】配置项 SkipHeapFreeLeaks

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍 VLD 配置文件中配置项 SkipHeapFreeLeaks 的使用方法。同系列文章目录可见 《内存泄漏检测工具》目录 目录 说明 1. 配置文件使用说明 2. 设置是否跳过堆内存泄漏检测 2.1 测试代码 2.2 SkipHeapFreeLeaks = no 时的输出 2.3 Skip…

    C++ 2023年4月18日
    00
  • 2023.5.5 面向对象程序设计实验报告

    实验项目名称:模板 一、实验目的 1、熟练掌握函数模板和类模板的定义格式。 2、熟练运用函数模板和类模板解决实际问题。 二、实验内容 1、复数类Complex有两个数据成员:a和b, 分别代表复数的实部和虚部,并有若干构造函数和一个重载-(减号,用于计算两个复数的距离)的成员函数。 要求设计一个函数模板 template < class T > …

    C++ 2023年5月5日
    00
合作推广
合作推广
分享本页
返回顶部