《洛谷深入浅出进阶篇》 P1496火烧赤壁——初识离散化

上链接:

P1496 火烧赤壁 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1496上题干:

有一组序列,[-2^31,2^31] , 现在给你n次操作,每一次操作给出两个整数l,r,代表一个子区间的左端点和右端点,[l,r)这就算覆盖一次。求所有的被覆盖的区间的长度

 例如:现在有一个序列:

给你三对数字,代表着区间的左端点和右端点,你分别对这些区间进行染色:

[1,3) 

[ 2,6)

[4,8) 

可以求出,经过这三次操作,被覆盖的区间的长度:

由于数据很小,所以我们可以用数组标记法:

枚举每次给出的区间,我们将区间内的数字打上标记,然后计算所有被打上标记的数有多少个就行了。

可以求出一共7个格子被覆盖了。

那么假如我给出以下的数据,数组标记法还能用吗?

[-2^31,-2^16)

[-65462131,-16846952)

[0,465)

[241,1321464)

[32137946,2^31)

首先,我们可以看出来,数组标记法,一定是行不通的。

首先数组下标是不能为负数,另外,数据达到了2^31,远远超出了数组能开辟的空间

时空复杂度也是个惊人数字

所以我们必须想办法来优化我们的思路。

其实

对于我们每一个给出的区间,

它们被覆盖的长度就是(右端点-左端点)

只不过有些区间是互相有一部分覆盖了而已。

那么应该怎么办呢?

有些人可能会想,我们只要计算出总长度,然后减去一次重复的区域。

这样或许可以,但,我们可以从根本入手

我们只需要想办法将这些会重复计算的地方只计算一次,那么问题就迎难而解了。

怎么才能只计算一次?————单元化计算(其实这也就是数组标记的思想)

还是上面那个例子:

给出三对区间

第一对区间:[1,3)

找到这个区间的两个端点:1,3

将 [1,3) 所在的区间打上标记(别忘记左闭右开)

也就是,  1  , 2 被打上了标记(这标记有什么用,后面就知道了)

第二对区间:[2,6) 

找到这个区间的端点:2,6

将 [2,6) 所在的区间打上标记

也就是,  2,3,4,5  被打上了标记

第三对区间:[4,8)

依次类推:

那么被打上标记的数字就是这些:

-3  -2 -1  0  1  2  3  4  5  6  7  8 9 10 11 

我们只要对所有打上标记的数字进行一项操作:ans = a[i+1] - a[i]   (差分的思想)

并将这个操作累加起来:ans += a[i+1] - a[i]   

ans = 2-1 + 3-2  + 4-3 + 5-4  + 6-5 + 7-6  + 8-7 = 7

这样的话,我们就不需要考虑会不会有重复区间的情况了,因为所有的数据只算了一遍

到这里,可能有些人坐不住了,你这有啥用啊,这么麻烦,还不如我直接手算呢。

欸,别急,这些只是小数据罢了,等到它是大数据的时候,就很有效果了。

另外,这样的操作,虽然看上去复杂,但是很好实现啊,你难道没发现每一步都是程序化的步骤么,所以有时候我们要站在电脑的角度去思考,瞪眼法虽好,但是很难以用程序来实现。

所以我们就可以引入离散化了(排序,去重,二分查找)

将每一对区间的左右端点当成一个个散点,将其放入数组里面:(这里不清楚的就去看看离散化的概念,很简单的,等你明白离散化是啥了之后再回来看看)

一共六组数字

[-2^31,-2^16)

[-65462131,-16846952)

[0,465)

[241,1321464)

[32137946,2^31)

数组下标12345678910
散点-2^31-2^16-65462131-1684695204652411321464321379462^31

将这一串数字进行排序:

数组下标12345678910
散点-2^31-65462131-16846952-2^1602414561321464321379462^31

紧接着把这个数组进行去重:(本组数据没有重复的,所以忽略) 

离散化的最后一步就是二分查找数据的位置

并结合我们刚刚说过的概念:单元化处理。

还记得单元化处理的第一步是什么吗?(翻上去看看)

找到第一对区间的端点在数组中的位置:(用二分查找找端点,这也就是为什么我们要去重的原因)

第一对端点:-2^31,   -2^16

可以用lower_bound()来进行二分

也可以用手动二分查找

得到位置:1,4

所以我们给[1,4)打上标记(不知道为啥打标记的翻上去看那个更简单的例子,再简单描述一下就是为了方便一项一项地处理,并且所有的数只会计算一次,不信的话你随便写几对数字模拟一下)

打标记:flag[i]=1

以此类推。

最后一步就是单项求和:

如果这个数字被打上了标记,那么我们就进行单元化处理 ans+= a[i+1] - a[i]

最后输出ans就好了

上代码:

const int N = 2e4 + 10;
int n, l[N], r[N], flag[2 * N], temp[2 * N], a,b ;
long long fn[2 * N], ans;
int main()
{cin >> n;for (int i = 1; i <= n; i++){cin >> l[i] >> r[i];temp[++a] = l[i];temp[++a] = r[i];}sort(temp + 1, temp + 1 + a);for (int i = 1; i <= a;i++){if (i == 1 or temp[i] != temp[i - 1])fn[++b] = temp[i];}for (int i = 1; i <= n; i++){int L = lower_bound(fn + 1, fn + 1 + b, l[i]) - fn;int R = lower_bound(fn + 1, fn + 1 + b, r[i]) - fn;for (int j = L; j < R; j++)flag[j] = 1;}for (int i = 1; i < b; i++)if (flag[i])ans += fn[i + 1] - fn[i];cout << ans;
}

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

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

相关文章

TikTok与心灵成长:娱乐与启发并重

社交媒体已成为我们生活的一部分&#xff0c;其中TikTok以其短视频内容和创新性而闻名。然而&#xff0c;TikTok不仅仅是一个娱乐平台&#xff0c;它还具有潜力成为心灵成长的有力工具。本文将探讨TikTok如何在娱乐与启发之间取得平衡&#xff0c;以促进心灵成长和积极影响。 娱…

java常用的几个图片处理工具对Tiff文件的支持

ImageMagick 官网 https://imagemagick.org/&#xff0c; 支持多种格式。命令行工具很适合调试。功能很强大. 还有一款工具GraphicsMagick 是从ImageMagick的基础上研发出来的。 OpenCV 官网 https://opencv.org/ &#xff0c; github地址https://github.com/opencv/opencv&…

2024年春季3月退役的大学生士兵免试专升本单独报名的新政策

关于2024年春季3月退役大学生士兵专升本免试单独报名安排的通知 2024年3月退役的符合条件的大学生士兵单独组织一次报名&#xff0c;网上报名时间另行通知&#xff0c;履行网上报名和信息确认手续&#xff0c;根据要求上传本人头像照片、身份证照片&#xff0c;以及《入伍通知书…

第六届浙江省大学生网络与信息安全竞赛 2023年 初赛/决赛 WEB方向 Writeup

-------------------【初赛】------------------- easy php 简单反序列化 __debuginfo()魔术方法打印所需调试信息&#xff0c;反序列化时候执行&#xff01; 链子如下&#xff1a; BBB::__debuginfo()->CCC::__toString()->AAA::__call()EXP&#xff1a; <?php…

如何以编程方式获取Android手机的电话号码?

在创建Android应用程序时,很多时候我们需要通过手机号码进行身份验证。为了增强用户体验,我们可以在移动系统中自动检测手机号码。因此,让我们开始一个android项目吧!我们将创建一个按钮,单击它时将获得一个手机号码并将其显示在 TextView 中。 分步实施 步骤 1:创建新项…

电机应用-控制系统、PID

控制系统 对生产中某些关键性参数进行自动控制&#xff0c;使它们在受到外界干扰&#xff08;扰动&#xff09;的影响而偏离正常状态时&#xff0c;能够被自动地调节而回到工艺所要求地数值范围内。 自动控制系统分为&#xff1a;开环、闭环。 闭环自动控制系统原理 闭环控制是…

ElasticStack日志分析平台-Filebeat与Logstash

一、ELK 1、介绍&#xff1a; ELK 是一个用于日志管理和数据分析的开源工具栈&#xff0c;它由三个主要组件组成&#xff1a; ① Elasticsearch: Elasticsearch 是一个实时分布式搜索和分析引擎&#xff0c;作用是存储和检索大规模数据&#xff0c;Elasticsearch 支持实时索…

03-CSS基础选择器

3.1 CSS基础认知&#x1f34e; 3.1.1 &#x1f441;️‍&#x1f5e8;️CSS概念 CSS&#xff1a;层叠样式表&#xff08;Cascading style sheets)&#xff0c;为网页标签增加样式表现的 语法格式&#xff1a; 选择器{<!-- 属性设置 -->属性名:属性值; <!--每一个…

Avatar虚拟形象解决方案,趣味化的视频拍摄与直播新体验

企业们正在寻找新的方式来吸引和保持观众的注意力,一种新兴的解决方案就是使用Avatar虚拟形象技术&#xff0c;这种技术可以让用户在视频拍摄或直播场景中&#xff0c;以自定义的数字人形象出现&#xff0c;同时保持所有的表情和脸部驱动。美摄科技正是这个领域的领军者&#x…

实用干货丨Eolink Apikit 配置和告警规则的各种用法

API在运行过程中可能会遇到各种异常情况&#xff0c;如响应时间过长、调用频率过高、请求参数错误等&#xff0c;这些异常会对系统的稳定性和性能产生严重影响。因此&#xff0c;对API进行异常监控和告警是非常必要的。本文将介绍 Eolink Apikit 中使用的告警规则&#xff0c;帮…

C++初阶,详解类和对象(2)

详解类和对象&#xff08;2&#xff09; 一&#xff0c;前言二&#xff0c;构造函数2.1构造函数概念2.2构造函数特性 三&#xff0c;析构函数3.1析构函数概念3.2析构函数特性 一&#xff0c;前言 上一篇我们讲了类的大体框架&#xff0c;这篇内容我们要重点来说一说类的几个默…

竞赛 题目:基于卷积神经网络的手写字符识别 - 深度学习

文章目录 0 前言1 简介2 LeNet-5 模型的介绍2.1 结构解析2.2 C1层2.3 S2层S2层和C3层连接 2.4 F6与C5层 3 写数字识别算法模型的构建3.1 输入层设计3.2 激活函数的选取3.3 卷积层设计3.4 降采样层3.5 输出层设计 4 网络模型的总体结构5 部分实现代码6 在线手写识别7 最后 0 前言…