[题解]CF1401E.Divide Square(codeforces 05)

题目描述

There is a square of size 106×106106×106 on the coordinate plane with four points (0,0)(0,0) , (0,106)(0,106) , (106,0)(106,0) , and (106,106)(106,106) as its vertices.

You are going to draw segments on the plane. All segments are either horizontal or vertical and intersect with at least one side of the square.

Now you are wondering how many pieces this square divides into after drawing all segments. Write a program calculating the number of pieces of the square.

输入格式

The first line contains two integers 𝑛n and 𝑚m ( 0≤𝑛,𝑚≤1050≤n,m≤105 ) — the number of horizontal segments and the number of vertical segments.

The next 𝑛n lines contain descriptions of the horizontal segments. The 𝑖i -th line contains three integers 𝑦𝑖yi​ , 𝑙𝑥𝑖lxi​ and 𝑟𝑥𝑖rxi​ ( 0<𝑦𝑖<1060<yi​<106 ; 0≤𝑙𝑥𝑖<𝑟𝑥𝑖≤1060≤lxi​<rxi​≤106 ), which means the segment connects (𝑙𝑥𝑖,𝑦𝑖)(lxi​,yi​) and (𝑟𝑥𝑖,𝑦𝑖)(rxi​,yi​) .

The next 𝑚m lines contain descriptions of the vertical segments. The 𝑖i -th line contains three integers 𝑥𝑖xi​ , 𝑙𝑦𝑖lyi​ and 𝑟𝑦𝑖ryi​ ( 0<𝑥𝑖<1060<xi​<106 ; 0≤𝑙𝑦𝑖<𝑟𝑦𝑖≤1060≤lyi​<ryi​≤106 ), which means the segment connects (𝑥𝑖,𝑙𝑦𝑖)(xi​,lyi​) and (𝑥𝑖,𝑟𝑦𝑖)(xi​,ryi​) .

It's guaranteed that there are no two segments on the same line, and each segment intersects with at least one of square's sides.

输出格式

Print the number of pieces the square is divided into after drawing all the segments.

输入输出样例
  • 输入#1

    复制
    3 3
    2 3 1000000
    4 0 4
    3 0 1000000
    4 0 1
    2 0 5
    3 1 1000000

    输出#1

    复制
    7
说明/提示

The sample is like this:

这个问题实际上是在考察我们如何有效地处理线段覆盖以及段分割的区域数量。下面是一些解题的思路和步骤:

步骤一:理解题意

首先,我们需要理解题目要求的是在给定一系列水平和垂直线段后,整个正方形被分成了多少个部分。每个线段都在正方形内部或与其边界相交,并且没有两条线段在同一水平线上或同一垂直线上。

步骤二:分析关键数据结构

  • 水平线段列表:存储所有水平线段的信息,即它们的高度和左右端点位置。
  • 垂直线段列表:存储所有垂直线段的信息,即它们的位置和上下端点位置。

步骤三:预处理

对水平线段和垂直线段进行排序,这样可以方便后续的处理。排序的关键在于水平线段按高度排序,而垂直线段按位置排序。

步骤四:构建扫描线算法

我们可以使用扫描线算法来解决这个问题。具体来说,我们可以在水平方向上“扫描”整个正方形,每次遇到一个水平线段时,就检查它与当前已知的所有垂直线段的交点。这个过程可以使用一个平衡树(例如红黑树或AVL树)来存储当前扫描线上所有的垂直线段的交点,这使得我们能够快速地找到新的交点并更新结果。

步骤五:计算分割区域的数量

每当我们遇到一个新的水平线段时,通过比较相邻两个交点之间的距离,我们可以确定新增加了多少个区域。这是因为每个新的交点都会在之前存在的区域内添加至少一个新区域。我们可以通过平衡树来维护这些信息,从而高效地计算出最终的区域步骤六:实现细节

  • 在实现过程中,需要特别注意边界条件的处理,比如当扫描线遇到正方形的边界时应该如何处理。
  • 考虑到输入,优化数据结构的选择和操作效率至关重要。

总结

这个问题是一个典型的扫描线算法的应用场景,通过有效的数据结构和算法设计,我们可以将复杂的问题简化为一系列更小的子问题。希望这些思路能帮助你开始解决这个问题,记住,在实际编码时,一步步调试和测试你的代码是非常你发现并修正潜在的错误。

代码优化点

  1. 分离关注点:将输入读取、数据处理和输出结果分开,增加代码的可读性和可维护性。

  2. 避免重复计算:在处理竖向线段时,直接计算贡献而不是逐个查询树状数组。

  3. 使用更现代的 C++ 特性:如 std::vector 和 std::map 来代替部分静态数组,这可以减少代码量并提供更好的安全性。

优化后的代码示例

#include <bits/stdc++.h>
using namespace std;const int MAXN = 1e6 + 5;
const int B = 1e6;struct BinaryIndexTree {vector<int> c;inline int) { return x & (-x); }inline void modify(int x, int d) {for (; x < c.size(); x += lowbit(x)) c[x] += d;}inline int query(int x) {int ans = 0;for (; x; x -= lowbit(x)) ans += c[x];return ans;}
};struct Node {int x, y, d;bool operator < (const Node& rhs) const { return x < rhs.x; }
};struct vLine {int x, l, r;bool operator < (const vLine& rhs) const { return x < rhs.x; }
};int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int n, m;cin >> n >> m;vector<Node> seq;vector<vLine> vln;vector<int> yCoords;for (int i = 0; i < n; ++i) {int y, l, r;cin >> y >> l >> r;if (l == 0 && r == B) ++n; // Adjusting initial regions countseq.emplace_back(l, y, 1);seq.emplace_back(r + 1, y, -1);yCoords.push_back(y);}for (int i = 0; i < m; ++i) {int x, l, r;cin >> x >> l >> r;if (l == 0 && r == B) ++n;v, l, r);}sort(begin(seq), end(seq));sort(begin(vln), end(vln));BinaryIndexTree bit;bit.c.resize(MAXN);int j = 0;long long ans = n;for (const auto& vl : vln) {while (j < seq.size() && seq[j].x <= vl.x) {++j;bit.modify(seq[j].y + 1, seq[j].d);}ans += bit.query(vl.r + 1) - bit.query    }cout << ans << '\n';return 0;
}

解释

  • 使用 std::vector 替代了静态数组,提供了动态分配内存的能力,并简化了数组操作。
  • 使用 std::cin 和 std::cout 替换了 scanf 和 printf,虽然这在性能上可能有轻微的影响,但增加了代码的可读性和现代感。
  • 将树状数组的大小动态分配,避免了硬编码的上限。

这些改动没有改变算法的核心逻辑,而是提高了代码的质量和可维护性。

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

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

相关文章

【数据结构】顺序表(ArrayList的具体使用)

&#x1f387;&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳&#xff0c;欢迎大佬指点&#xff01; 欢迎志同道合的朋友一起加油喔 &#x1f4aa;&#x1f4aa;&#x1f4aa; 谢谢你这么帅…

VSCode STM32嵌入式开发插件记录

要卸载之前搭建的VSCode嵌入式开发环境了&#xff0c;记录一下用的插件。 1.Cortex-Debug https://github.com/Marus/cortex-debug 2.Embedded IDE https://github.com/github0null/eide 3.Keil uVision Assistant https://github.com/jacksonjim/keil-assistant/ 4.RTO…

支持向量机(SVM,Support Vector Machine)

支持向量机&#xff08;SVM&#xff0c;Support Vector Machine&#xff09;是一种监督学习模型&#xff0c;主要用于分类和回归分析。它的优点包括&#xff1a; 优点&#xff1a; 高效解决高维问题&#xff1a;通过核函数可以将低维数据映射到高维空间&#xff0c;使得非线性…

政安晨【零基础玩转各类开源AI项目】基于Ubuntu系统部署MimicMotion :利用可信度感知姿势指导生成高质量人体运动视频

目录 项目介绍 项目相关工作 图像/视频生成的扩散模型 姿势引导的人体动作转移 生成长视频 方法实践 与最先进方法的比较 消融研究 部署验证 1. 下载项目&#xff1a; 2. 建立环境 3. 下载参数模型 A. 下载 DWPose 预训练模型&#xff1a;dwpose B. 从 Huggingfa…

学术研究期刊

投稿指南 一、《学术研究》投稿须知   来稿需为作者的原创性研究成果&#xff0c;除了文中特别加以标注和致谢的地方外&#xff0c;不包含他人已经发表或者撰写过的研究成果&#xff0c;也不包含作者已经发表的研究成果。如发现学术不端行为&#xff0c;本刊将追究相关责任人…

DDD(3)-领域驱动设计之如何建模

前言 上一篇&#xff1a;从领域驱动到模型驱动中我们讨论到&#xff0c;领域驱动设计的核心思想是保持业务-模型-代码的一致性&#xff0c;模型作为沟通业务和代码的工具&#xff0c;至关重要&#xff0c;今天这篇文章就来讨论DDD中建模的一些思考和方法。 什么是建模 虽然看…

基于SSM的高考志愿选择辅助系统

基于SSM的高考志愿选择辅助系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台 前台首页 院校展示 后台 后台首页 学校管理 摘要 随着高考制度的不断完…

【Drone】drone编译web端 防墙策略 | 如何在被墙的状态drone顺利编译npm

一、drone编译防墙版本 1、web端drone kind: pipeline type: docker name: ui steps:- name: build_projectimage: node:20-slim depends_on: [clone]volumes:- name: node_modulespath: /drone/src/node_modulescommands:- pwd- du -sh *- npm config set registry https://…

前端使用 Konva 实现可视化设计器(18)- 素材嵌套 - 加载阶段

本章主要实现素材的嵌套&#xff08;加载阶段&#xff09;这意味着可以拖入画布的对象&#xff0c;不只是图片素材&#xff0c;还可以是嵌套的图片和图形。 请大家动动小手&#xff0c;给我一个免费的 Star 吧~ 大家如果发现了 Bug&#xff0c;欢迎来提 Issue 哟~ github源码 g…

测试——Selenium

内容大纲: 什么是自动化测试 什么是Selenium Selenium工作原理 Selenium环境搭建 Selenium API 目录 1. 什么是自动化测试 2. 什么是Selenium 3. Selenium工作原理 4. Selenium环境搭建(java) 5. Selenium API 5.1 定位元素 5.1.1 CSS选择器定位元素 5.1.2 XPath定位元…

PHP进阶:前后端交互、cookie验证、sql与php

单词&#xff1a;construct 构造 destruct 摧毁 empty 空的 trim 修剪 strip 清除 slash 斜线 special 特殊 char 字符 query 询问 构造方法&#xff08;魔术方法&#xff09; 构造方法是一种特殊的函数&#xff0…

QT 4.8版本的Ubuntu2004编译错误的解决方案

arm-linux-gnueabihf-gcc 5.2编译qt4.8.5_error: ‘class ui::qprintpropertieswidget’ has no m-CSDN博客

k8s中部署nacos

1 部署nfs # 在k8s的主节点上执行 mkdir -p /appdata/download cd /appdata/download git clone https://github.com/nacos-group/nacos-k8s.git 将nacos部署到middleware的命名空间中 kubectl create namespace middleware cd /appdata/download/nacos-k8s # 创建角色 kub…

VScode连接虚拟机运行Python文件的方法

声明&#xff1a;本文使用Linux发行版本为rocky_9.4 目录 1. 在rocky_9.4最小安装的系统中&#xff0c;默认是没有tar工具的&#xff0c;因此&#xff0c;要先下载tar工具 2. 在安装好的vscode中下载ssh远程插件工具 3. 然后连接虚拟机 4. 查看python是否已经安装 5. 下载…

linux代填密码切换用户

一、背景 linux用户账户密码复杂&#xff0c;在不考虑安全的情况下&#xff0c;想要使用命令自动切换用户 二、操作 通过 expect 工具来实现自动输入密码的效果 yum install expect创建switchRoot.exp文件&#xff0c;内容参考下面的 #!/usr/bin/expect set username root…

【状态估计】偏差,匹配和外点

我们都知道&#xff1a;对于状态的估计可能是有偏差的&#xff0c;特别是在运动模型或观测模型是非线性的情况下。在简单的立体相机的例子中&#xff0c;我们看到MAP方法相比于全贝叶斯方法来说是有偏差的。同时&#xff0c;我们也看到批量ML方法对于真实值来说也是有偏差的&am…

openEuler操作系统下Oracle 19c 从19.3补丁更新到19.17

Oracle 19c 从补丁19.3更新到19.17的过程涉及到多个步骤&#xff0c;包括备份、下载补丁、替换OPatch、验证清单信息、冲突检测、空间检测、应用补丁等。以下是一个概括性的流程&#xff0c;但请注意&#xff0c;具体步骤可能会根据实际的Oracle环境、补丁内容和Oracle的官方指…

【接口自动化_07课_Pytest+Excel+Allure完整框架集成_下】

目标&#xff1a;优化框架场景 1. 生成对应的接口关联【重点】 2. 优化URL基础路径封装【理解】 3. 利用PySQL操作数据库应用【理解】--- 怎么用python连接数据库、mysql 4. 通过数据库进行数据库断言【重点】 5. 通过数据库进行关联操作【重点】 一、接口关联&#xff1a…

【数据中心】数据中心的IP封堵防护:构建网络防火墙的基石

数据中心的IP封堵防护&#xff1a;构建网络防火墙的基石 引言一、理解IP封堵二、IP封堵的功能模块及其核心技术三、实施IP封堵的关键策略四、结论 引言 在当今高度互联的世界里&#xff0c;数据中心成为信息流动和存储的神经中枢&#xff0c;承载着企业和组织的大量关键业务。…

【QAC】分布式部署下其他机器如何连接RLM

1、 文档目标 解决分布式部署下其他机器如何连接RLMLicense管理器。 2、 问题场景 分布式部署下QAC要在其他机器上单独运行扫描&#xff0c;必须先连接RLMLicense管理器&#xff0c;如何连接&#xff1f; 3、软硬件环境 1、软件版本&#xff1a;HelixQAC23.04 2、机器环境…