信奥赛C++提高组csp-s之离散化

信奥赛C++提高组csp-s之离散化

1. 什么是离散化?

离散化是一种将无限或大范围的数据映射到有限、连续的小范围内的技术。

为什么需要离散化?
  • 数据范围太大,无法直接作为数组下标(如109 ^99
  • 只需要数据的相对大小关系,不需要具体数值
  • 节省内存空间
  • 便于使用数组、线段树等数据结构
2. 离散化的基本原理
基本思想
原始数据: [1000, 200000, 300, 1000, 5000] 离散化后: [1, 3, 0, 1, 2]

保持原始数据的大小关系不变,但将数值压缩到小范围内。

3. 离散化的实现方法
方法一:排序 + 去重 + 二分查找(最常用)
#include<bits/stdc++.h>usingnamespacestd;// 离散化函数vector<int>fun(vector<int>&nums){vector<int>tmp=nums;// 1. 排序sort(tmp.begin(),tmp.end());// 2. 去重tmp.erase(unique(tmp.begin(),tmp.end()),tmp.end());// 3. 二分查找映射vector<int>result;for(intx:nums){intpos=lower_bound(tmp.begin(),tmp.end(),x)-tmp.begin();result.push_back(pos);// 或 pos+1 如果要从1开始}returnresult;}
方法二:使用map自动排序和去重
vector<int>fun(vector<int>&nums){vector<int>tmp=nums;sort(tmp.begin(),tmp.end());tmp.erase(unique(tmp.begin(),tmp.end()),tmp.end());unordered_map<int,int>m;for(inti=0;i<tmp.size();i++){m[tmp[i]]=i;}vector<int>result;for(intx:nums){result.push_back(m[x]);}returnresult;}
4. 研究案例
题目背景

曹操平定北方以后,公元 208 年,率领大军南下,进攻刘表。他的人马还没有到荆州,刘表已经病死。他的儿子刘琮听到曹军声势浩大,吓破了胆,先派人求降了。

孙权任命周瑜为都督,拨给他三万水军,叫他同刘备协力抵抗曹操。

隆冬的十一月,天气突然回暖,刮起了东南风。

没想到东吴船队离开北岸大约二里距离,前面十条大船突然同时起火。火借风势,风助火威。十条火船,好比十条火龙一样,闯进曹军水寨。那里的船舰,都挤在一起,又躲不开,很快地都烧起来。一眨眼工夫,已经烧成一片火海。

曹操气急败坏的把你找来,要你钻入火海把连环线上着火的船只的长度统计出来!

题目描述

给定每个起火部分的起点和终点,请你求出燃烧位置的长度之和。

输入格式

第一行一个整数,表示起火的信息条数n nn
接下来n nn行,每行两个整数a , b a, ba,b,表示一个着火位置的起点和终点(注意:左闭右开)。

输出格式

输出一行一个整数表示答案。

输入样例 1
3 -1 1 5 11 2 9
输出样例 1
11
数据规模与约定

对于全部的测试点,保证1 ≤ n ≤ 2 × 10 4 1 \leq n \leq 2 \times 10^41n2×104− 2 31 ≤ a < b < 2 31 -2^{31} \leq a < b \lt 2^{31}231a<b<231,且答案小于2 31 2^{31}231

思路分析

这道题的核心是区间合并问题。给定多个区间(左闭右开),需要计算这些区间覆盖的总长度,重叠部分只计算一次。

解题思路:
  1. 离散化:由于坐标范围很大(− 2 31 到 2 31 -2^{31}到2^{31}231231),直接开数组会内存溢出,所以需要将坐标离散化
  2. 标记覆盖:将每个区间映射到离散化后的坐标上,标记被覆盖的区间段
  3. 计算总长:遍历所有离散化后的区间段,累加被标记的区间长度
具体步骤:
  1. 读入所有区间,收集所有端点值
  2. 对端点进行排序并去重(离散化)
  3. 将每个原始区间映射到离散化后的下标范围
  4. 用布尔数组标记每个离散化区间段是否被覆盖
  5. 累加所有被标记的区间段的长度
代码实现
#include<bits/stdc++.h>usingnamespacestd;typedefpair<int,int>PII;// 定义区间对类型intn;intmain(){cin>>n;vector<PII>segs;// 存储原始区间vector<int>alls;// 存储所有端点,用于离散化// 读入数据并收集所有端点for(inti=1;i<=n;i++){inta,b;cin>>a>>b;segs.push_back({a,b});// 存储原始区间alls.push_back(a);// 收集左端点alls.push_back(b);// 收集右端点}// 离散化处理sort(alls.begin(),alls.end());// 对所有端点排序// 去重,unique返回去重后的尾迭代器alls.erase(unique(alls.begin(),alls.end()),alls.end());// c数组标记离散化后的区间段是否被覆盖// 每个区间段对应alls中相邻两个端点之间的部分vector<bool>c(alls.size()-1,false);// 处理每个原始区间,标记覆盖的区间段for(autoseg:segs){// 使用二分查找找到端点在离散化数组中的位置intl=lower_bound(alls.begin(),alls.end(),seg.first)-alls.begin();intr=lower_bound(alls.begin(),alls.end(),seg.second)-alls.begin();// 标记[l, r)之间的所有区间段为已覆盖// 注意:这里是i<r,因为是左闭右开区间for(inti=l;i<r;i++){c[i]=true;}}// 计算总长度longlongans=0;for(inti=0;i<c.size();i++){if(c[i]){// 如果第i个区间段被覆盖,累加其长度// 长度 = alls[i+1] - alls[i]ans+=(alls[i+1]-alls[i]);}}cout<<ans<<endl;return0;}
功能分析
1. 数据结构设计
  • segs: 存储原始的起火区间
  • alls: 存储所有端点坐标,用于离散化
  • c: 布尔数组,标记离散化后的每个小区间是否被覆盖
2. 核心算法流程
  • 离散化阶段:将所有端点排序、去重,将无限空间映射到有限下标
  • 区间映射阶段:将每个原始区间[a,b)映射到离散化后的下标范围[l,r)
  • 标记阶段:标记所有被覆盖的离散化区间
  • 计算阶段:累加被标记区间的实际长度
3. 关键点说明
  • 离散化必要性:坐标范围达到2^31,直接开数组会MLE
  • 二分查找优化lower_bound在有序数组中快速定位坐标
  • 区间处理:注意题目是左闭右开区间,循环条件为i<r
  • 长度计算:离散化后每个区间段长度需要还原为原始坐标差
4. 复杂度分析
  • 时间复杂度:O(n log n),主要开销在排序和二分查找
  • 空间复杂度:O(n),存储端点数组和标记数组
5. 示例解释

对于输入:

3 -1 1 5 11 2 9

处理过程:

  1. 所有端点:-1, 1, 5, 11, 2, 9 → 排序去重后:-1, 1, 2, 5, 9, 11
  2. 离散化区间段:[-1,1), [1,2), [2,5), [5,9), [9,11)
  3. 标记覆盖:
    • [-1,1) → 覆盖
    • [5,11) → 覆盖[5,9)和[9,11)
    • [2,9) → 覆盖[2,5)和[5,9)
  4. 总长度:(-1到1) + (2到5) + (5到9) + (9到11) = 2 + 3 + 4 + 2 = 11
5. 离散化的注意事项
要点总结:
  1. 保持顺序:离散化后要保持原始数据的大小关系
  2. 去重是必须的:相同的值应该映射到同一个离散值
  3. 边界处理:考虑是从0开始还是从1开始(树状数组通常从1开始)
  4. 内存管理:离散化数组大小 = 不同元素的个数
  5. 查询效率:使用二分查找 O(logn)
常见错误:
// 错误:忘记去重sort(alls.begin(),alls.end());// 缺少:alls.erase(unique(alls.begin(), alls.end()), alls.end());// 错误:二分查找写错// 正确应该是 lower_bound,不是 upper_bound
6. 离散化的时间复杂度分析
步骤时间复杂度说明
排序O(nlogn)主要开销
去重O(n)线性扫描
映射O(nlogn)n次二分查找
总计O(nlogn)通常可以接受
7. 练习题推荐
  1. 基础练习

    • 统计每个数出现的次数(数据范围大)
    • 区间和查询(AcWing 802)
  2. 进阶练习

    • 求逆序对数量(配合树状数组)
    • 扫描线问题(矩形面积并)
    • 数星星问题(二维偏序)
8. 模板代码
// 离散化通用模板classDiscretizer{private:vector<int>vals;public:voidadd(intx){vals.push_back(x);}voiddiscretize(){sort(vals.begin(),vals.end());vals.erase(unique(vals.begin(),vals.end()),vals.end());}intget_id(intx){returnlower_bound(vals.begin(),vals.end(),x)-vals.begin()+1;}intsize(){returnvals.size();}};
总结

离散化是信奥赛中的重要技巧,主要用于:

  1. 处理大数据范围但数据量小的问题
  2. 将数据映射到连续区间,便于使用数组等数据结构
  3. 与树状数组、线段树等结合解决统计问题

掌握离散化的关键在于理解其"保持顺序、压缩空间"的核心思想,并熟练运用排序、去重、二分查找这三个基本操作。

更多系列知识,请查看专栏:《信奥赛C++提高组csp-s知识详解及案例实践》:
https://blog.csdn.net/weixin_66461496/category_13113932.html

各种学习资料,助力大家一站式学习和提升!!!

#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"########## 一站式掌握信奥赛知识! ##########";cout<<"############# 冲刺信奥赛拿奖! #############";cout<<"###### 课程购买后永久学习,不受限制! ######";return0;}
  • 一、CSP信奥赛C++通关学习视频课:
    • C++语法基础
    • C++语法进阶
    • C++算法
    • C++数据结构
    • CSP信奥赛数学
    • CSP信奥赛STL
  • 二、CSP信奥赛C++竞赛拿奖视频课:
    • 信奥赛csp-j初赛高频考点解析
    • CSP信奥赛C++复赛集训课(12大高频考点专题集训)
  • 三、csp高频考点知识详解及案例实践:
    • CSP信奥赛C++之动态规划
    • CSP信奥赛C++之标准模板库STL
    • 信奥赛C++提高组csp-s知识详解及案例实践
  • 四、考级、竞赛刷题题单及题解:
    • GESP C++考级真题题解
    • CSP信奥赛C++初赛及复赛高频考点真题解析
    • CSP信奥赛C++一等奖通关刷题题单及题解

详细内容:

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转


2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html

4、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

CSP信奥赛C++一等奖通关刷题题单及题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

· 文末祝福 ·

#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"跟着王老师一起学习信奥赛C++";cout<<" 成就更好的自己! ";cout<<" csp信奥赛一等奖属于你! ";return0;}

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

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

相关文章

基于AUTOSAR的UDS 27服务ECU实现深度剖析

深入AUTOSAR安全内核&#xff1a;UDS 27服务的实战实现与工程精要在汽车电子开发中&#xff0c;诊断不再只是“读故障码”那么简单。随着智能网联车对安全性的要求日益严苛&#xff0c;如何防止未经授权的操作成为每一个ECU开发者必须面对的核心问题。而UDS 27服务&#xff08;…

毛球修剪器电路图详解:从零理解过流保护设计

毛球修剪器电路图详解&#xff1a;从零理解过流保护设计你有没有遇到过这样的情况——正在用毛球修剪器清理大衣上的起球&#xff0c;突然“嗡”的一声卡住不动了&#xff1f;再按开关也没反应。别急着换电池或拆机&#xff0c;很可能不是机器坏了&#xff0c;而是它的过流保护…

MediaPipe本地运行实战:彻底告别Token验证与网络中断问题

MediaPipe本地运行实战&#xff1a;彻底告别Token验证与网络中断问题 1. 引言&#xff1a;AI人体骨骼关键点检测的现实挑战 在计算机视觉领域&#xff0c;人体姿态估计&#xff08;Human Pose Estimation&#xff09;是实现动作识别、虚拟试衣、运动分析和人机交互的核心技术…

HY-MT1.5-1.8B优化实战:INT8量化让推理速度翻倍

HY-MT1.5-1.8B优化实战&#xff1a;INT8量化让推理速度翻倍 1. 引言 在全球化数字交流日益频繁的背景下&#xff0c;高效、精准的多语言翻译能力已成为智能应用的核心竞争力之一。腾讯混元团队于2025年12月开源的轻量级多语种神经翻译模型 HY-MT1.5-1.8B&#xff0c;凭借其“…

快速理解Elasticsearch下载在Windows中的运行机制

深入理解 Elasticsearch 在 Windows 上的运行机制&#xff1a;从下载到服务化部署 你是否曾在本地开发中尝试启动 Elasticsearch&#xff0c;却卡在“端口被占用”或“Java 内存不足”的报错上&#xff1f;又或者&#xff0c;明明双击了 elasticsearch.bat &#xff0c;窗口…

WinDbg监控驱动内存泄漏:实战案例解析

用WinDbg揪出驱动内存泄漏&#xff1a;一个真实案例的深度复盘你有没有遇到过这种情况——系统运行几天后越来越慢&#xff0c;最后“啪”一下蓝屏了&#xff1f;日志里翻来覆去都是PAGE_FAULT_IN_NONPAGED_AREA或者POOL_HEADER_CORRUPTION&#xff0c;但就是找不到元凶。这类问…

如何快速掌握DownKyi:面向新手的完整B站视频下载指南

如何快速掌握DownKyi&#xff1a;面向新手的完整B站视频下载指南 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#x…

MediaPipe Pose稳定性评测:零报错本地部署实战案例分享

MediaPipe Pose稳定性评测&#xff1a;零报错本地部署实战案例分享 1. 引言&#xff1a;AI人体骨骼关键点检测的工程挑战 随着AI在健身指导、动作识别、虚拟试衣等场景中的广泛应用&#xff0c;人体骨骼关键点检测&#xff08;Human Pose Estimation&#xff09;已成为计算机…

AI人体骨骼检测应用前景:元宇宙/虚拟人动作捕捉初探

AI人体骨骼检测应用前景&#xff1a;元宇宙/虚拟人动作捕捉初探 1. 引言&#xff1a;AI人体骨骼关键点检测的技术演进与价值 随着人工智能在计算机视觉领域的持续突破&#xff0c;人体骨骼关键点检测&#xff08;Human Pose Estimation&#xff09;正从实验室走向真实世界的大…

信奥赛C++提高组csp-s之KMP算法详解

信奥赛C提高组csp-s之KMP算法详解 一、KMP算法概述 KMP算法&#xff08;Knuth-Morris-Pratt算法&#xff09;是一种高效的字符串匹配算法&#xff0c;用于在文本串中查找模式串的出现位置。与朴素的暴力匹配相比&#xff0c;KMP算法的时间复杂度为O(nm)&#xff0c;其中n是文本…

边缘计算新选择:HY-MT1.5-1.8B轻量化部署全解析

边缘计算新选择&#xff1a;HY-MT1.5-1.8B轻量化部署全解析 随着多语言交流需求的不断增长&#xff0c;高质量、低延迟的翻译模型成为智能硬件和边缘计算场景中的关键技术。腾讯开源的混元翻译大模型&#xff08;HY-MT1.5&#xff09;系列&#xff0c;凭借其在翻译质量、多语言…

通俗解释LCD12864工作原理:小白也能懂

从零开始搞懂LCD12864&#xff1a;一块老屏背后的硬核逻辑你有没有在电表、温控器或者实验室设备上见过那种蓝底白字的屏幕&#xff1f;上面能显示“温度&#xff1a;37.5℃”、“菜单设置”甚至简单的图标——它很可能就是LCD12864。别看这玩意儿长得像古董&#xff0c;至今还…

AI骨骼关键点检测优化指南:MediaPipe Pose参数调整

AI骨骼关键点检测优化指南&#xff1a;MediaPipe Pose参数调整 1. 引言&#xff1a;AI人体骨骼关键点检测的工程挑战 随着计算机视觉技术的发展&#xff0c;人体姿态估计&#xff08;Human Pose Estimation&#xff09;已成为智能健身、动作捕捉、虚拟现实和人机交互等领域的…

MediaPipe Pose部署教程:零基础实现人体姿态估计

MediaPipe Pose部署教程&#xff1a;零基础实现人体姿态估计 1. 引言 1.1 学习目标 本文是一篇从零开始的实战教程&#xff0c;旨在帮助没有任何MediaPipe使用经验的开发者快速部署并运行一个高精度的人体姿态估计系统。通过本教程&#xff0c;你将掌握&#xff1a; 如何本…

DownKyi:B站视频下载神器,新手也能轻松掌握的8K视频收藏指南

DownKyi&#xff1a;B站视频下载神器&#xff0c;新手也能轻松掌握的8K视频收藏指南 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取…

从零实现CP2102 USB转UART硬件方案

手把手教你打造一个稳定可靠的CP2102 USB转UART模块 你有没有遇到过这样的场景&#xff1a;调试STM32时发现电脑没有串口&#xff0c;买来的CH340模块时不时掉驱动&#xff0c;或者在工业现场因为通信不稳定导致数据错乱&#xff1f;这些问题其实都指向同一个核心需求—— 一…

MediaPipe Pose实战:康复训练动作监测系统搭建

MediaPipe Pose实战&#xff1a;康复训练动作监测系统搭建 1. 引言 1.1 康复训练中的技术痛点 在现代康复医学中&#xff0c;患者的动作规范性直接影响治疗效果。传统的康复训练依赖治疗师肉眼观察和手动记录&#xff0c;存在主观性强、反馈滞后、难以量化等问题。尤其在远程…

AI骨骼检测WebUI使用教程:上传图片即得火柴人骨架图

AI骨骼检测WebUI使用教程&#xff1a;上传图片即得火柴人骨架图 1. 章节概述 随着AI在计算机视觉领域的深入发展&#xff0c;人体姿态估计&#xff08;Human Pose Estimation&#xff09;已成为智能健身、动作捕捉、虚拟试衣等场景的核心技术之一。本文将详细介绍一款基于 Go…

DownKyi完整攻略:掌握B站视频离线下载全流程

DownKyi完整攻略&#xff1a;掌握B站视频离线下载全流程 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#xff09;。 …

DownKyi终极指南:B站视频下载的10个专业技巧

DownKyi终极指南&#xff1a;B站视频下载的10个专业技巧 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#xff09;。 …