二分和离散化

为什么把二分和离散化放一起:因为离散化其实是一种二分整数的过程。

二分

相信大家都接触过二分查找(折半查找),这就是二分的思想。

二分通过每次舍弃一半并不存在答案的区间,进而快速锁定要求的答案(二分一定有解,但解不一定就是答案,后面会说)

二分模板:

bool check(int x) {/* ... */} // 检查x是否满足某种性质// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{while (l < r){int mid = l + r >> 1;if (check(mid)) r = mid;    // check()判断mid是否满足性质else l = mid + 1;}return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
int bsearch_2(int l, int r)
{while (l < r){int mid = l + r + 1 >> 1;if (check(mid)) l = mid;else r = mid - 1;}return l;
}

说一下版子二为什么要+1:因为涉及到mid - 1,+1是为了防止数组越界的,l < r ,所以r > 0,所以(  + r + 1 >> 1) > = 1,因而r更新的时候一定大于等于0,这也就防止了越界。

当然这只是针对于整数二分的边界问题,浮点数二分就不用考虑这个多了,直接除2就可以。

例题:

1、AcWing 789. 数的范围 - AcWing

2、AcWing 790. 数的三次方根 - AcWing

题一:直接套用两个模板,二分出左右区间。判断-1的方法:首次二分出来的区间的下标对应的数组元素并不等于给定要查找的那个数。

题二:不要的左右边界设置成-n 和 n,这样无法处理小数的情况,因为他们的三次方根都会落在-n到n范围的外面,但它也会有解。这也解释了为什么二分一定有解,但是解不一定是答案(解不对)

离散化

先来看一下百科的离散化的定义:

离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。

通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。例如:

原数据:1,999,100000,15;处理后:1,3,4,2;

原数据:{100,200},{20,50000},{1,400};

处理后:{3,4},{2,6},{1,5};

离散化,就是把一些分布很稀疏的数重新按着他的序号排序,比如我们现在有数据10^9、 1、 5000、 100000 这组数离散化之后的结果就是4、 1、 2、 3 可以看到结果其实就是他们的次序大小。

一般的我们先把这组数据排序然后在离散化,这样得到的结果就是1、2、3、4、5、6.... n.一组连续的整数,这样就可以存到数组里面然后随机访问。

当题目中给的数据范围很大,比如是-10^9到10^9,但是数据规模很小,如n = 10^5。这时候首当其中的就要考虑离散化。因为,我们无法创建一个合适大小的数组,所以基于数组随机访问的bucket等算法思想就无法使用,但当我们离散化之后就可以用一个10^5的数组去存放这些数,因为只有这些个数据有效。

在离散化的时候我们一般要考虑去重问题,可以理解成在同一个位置上存放两次数据,所以不需要给它重新分配下标。

然后说一下怎么去重:

unique函数:

他会把一段连续的数据内的相同元素删掉,并返回指向最后一个不重复元素的下一个地址的迭代器。

unique参数:两个维护范围的迭代器

这样我们就得到的了一个缩减版的数组和一个指向数组有效数据的下一个位置的指针,如果我们用vector的话调用erase函数把剩余的无效数据的部分释放掉就得到了一个无重复数据的容器。

现在我们得到了一个无重复数据的递增的vector,可以正式开始离散化了(离散化也是二分求下标的过程)。

离散化模板:

int find(int x)
{int l = 0, r = alls.size() - 1;while(l < r){int mid = l + r >> 1;if(alls[mid] >= x) r = mid;else l = mid + 1;}return r + 1;
}

解释一下参数:x为想要离散化数组的其中一个数据,返回值为离散化后的相对大小,或者叫新下标(这里是从1开始)。

例题:

这一题用得到知识点:离散化、前缀和、二分。

区间和

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

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

相关文章

如何测试模型推理精度:Python初学者指南

如何测试模型推理精度&#xff1a;Python初学者指南 什么是模型推理精度&#xff1f;使用工具包&#xff1a;lm-evaluation-harness安装工具包 测试模型推理精度的步骤1. 加载模型和分词器2. 使用 lm-evaluation-harness 进行测试3. 运行脚本4. 查看结果 总结 在机器学习和深度…

行为树详解(5)——事件驱动

【分析】 如果行为树的节点很多&#xff0c;那么会存在要经过很多节点才会走到动作节点的情况。显然&#xff0c;性能上不如状态机。 每帧都需要重新遍历一系列节点才会走到动作节点&#xff0c;而实际上很多条件节点在数帧内不会有变化&#xff0c;这是造成性能问题的重要原…

ESP-IDF学习记录(2)ESP-IDF 扩展的简单使用

傻瓜式记录一个示例的打开&#xff0c;编译&#xff0c;运行。后面我再一个个运行简单分析每个demo的内容。 1.打开示例代码 2.选择项目&#xff0c;文件夹 3.选择串口 4.选择调试方式 5.根据硬件GPIO口配置menuconfig 6.构建项目 7.烧录设备&#xff0c;选择串口UART方式 运行…

SpringMVC学习(一)——请求与响应处理

目录 一、SpringMVC简介 二、RequestMapping&#xff1a;请求路径映射 三、RestController 四、请求限定 五、请求处理 1.使用普通变量&#xff0c;收集请求参数 2.使用RequestParam明确指定获取参数 3.目标方法参数是一个pojo 4.RequestHeader&#xff1a;获取请求…

数据分析的分类和EDIT思维框架

为了服务于企业不同层次的决策&#xff0c;商业数据分析过程需要提供相应的数据科学产出物。 一般而言&#xff0c;数据分析需要经历从需求层、数据层、分析层到输出层四个阶段。 第一个阶段是需求层——确定目标&#xff0c;具体目标需要依据具体的层次进行分析&#xff1a…

实验五 时序逻辑电路部件实验

一、实验目的 熟悉常用的时序逻辑电路功能部件&#xff0c;掌握计数器、了解寄存器的功能。 二、实验所用器件和仪表 1、双 D触发器 74LS74 2片 2、74LS162 1片 3、74194 1片 4、LH-D4实验仪 1台 1.双…

iOS 中的 nil、Nil、NULL、NSNull 僵尸对象和野指针

iOS 中的 nil、Nil、NULL、NSNull 僵尸对象和野指针-CSDN博客 类型含义使用场景示例nil表示一个指向 Objective - C 对象的空指针。在 Objective - C 和 Swift&#xff08;与 Objective - C 交互时&#xff09;中用于表示对象不存在。当一个对象变量没有指向任何有效的对象实例…

JS面试题|[2024-12-28]

1.JS的设计原理是什么&#xff1f; JS引擎 运行上下文 调用栈 事件循环 回调 执行流程&#xff1a; JS引擎将代码解析为电脑可以执行的代码&#xff0c;调用一些API&#xff08;运行上下文&#xff09;让浏览器执行 JS是单线程的&#xff0c;每次从调用栈里面取出来的代码进行调…

全面了解 SQL Server:功能、优势与最佳实践

SQL Server 是微软公司推出的一款关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;广泛应用于企业级数据存储、数据分析、应用开发等领域。作为全球最受欢迎的数据库管理系统之一&#xff0c;SQL Server 提供了强大的功能和工具&#xff0c;支持从小型应用到大型…

jdk动态代理和cglib动态代理对比

jdk动态代理和cglib动态代理对比&#xff1a; CGLIB 和 JDK 动态代理都可以用来在运行时生成代理对象 1. 基本概念 JDK 动态代理&#xff1a;只代理接口&#xff08;interface&#xff09;&#xff0c;无法代理类。它使用 java.lang.reflect.Proxy 类和 java.lang.reflect.I…

给vscode的新项目选择虚拟环境

按照通常的步骤新建了.vscode文件并生成了launch.json&#xff0c;都是通过左栏的调试按钮里的create a json file&#xff0c;但是 运行时还是没有识别&#xff0c;之后看到下面的这个链接里&#xff0c;图中是在>之后选择的环境&#xff0c;于是&#xff1a; ctrlG出现搜索…

攻破 Kioptix Level 1 靶机

找教程然后自己练习&#xff0c;论菜狗的自我修养 基本步骤 1.确定目标IP 2.扫描端口&#xff0c;服务&#xff0c;版本信息&#xff0c;漏洞信息 3.查找漏洞可利用脚本 4.运行脚步 一、信息获取 arp-scan -l nmap -sS -p- -sV -sC -A --min-rate5000 192.168.5.130 二、查…

b站ip属地评论和主页不一样怎么回事

在浏览B站时&#xff0c;细心的用户可能会发现一个有趣的现象&#xff1a;某些用户的评论IP属地与主页显示的IP属地并不一致。这种差异引发了用户的好奇和猜测&#xff0c;究竟是什么原因导致了这种情况的发生呢&#xff1f;本文将对此进行深入解析&#xff0c;帮助大家揭开这一…

如何使用fetch函数获取多个数据并同时使用(在嵌套的fetch函数之间传递数据)

&#xff08;一&#xff09;问题描述 需要读取多个数据&#xff0c;也就是有多个fetch函数&#xff0c;但是这些数据又需要同时用。由于fetch是异步的&#xff0c;因此每个fetch单独进行是没有办法同时获得数据的&#xff0c;此时有两种可行的方式。 &#xff08;二&#xff…

音视频入门基础:MPEG2-PS专题(2)——使用FFmpeg命令生成ps文件

通过FFmpeg命令可以将mp4文件转换为ps文件。由于ps文件对应的FFInputFormat结构为&#xff1a; const FFInputFormat ff_mpegps_demuxer {.p.name "mpeg",.p.long_name NULL_IF_CONFIG_SMALL("MPEG-PS (MPEG-2 Program Stream)"),.p.flags …

帝国cms电脑pc站url跳转到手机站url的方法

本文讲解一下帝国cms电脑网站跳转到手机动态网站和手机静态网站的方法,笔者以古诗词网 www.gushichi.com为例&#xff0c;为大家介绍操作步骤。方法一&#xff1a;帝国pc站跳转到手机静态站 1、假设我们有帝国cms 电脑网站www.XXX.com&#xff0c;手机网站m.XXX.com &#xf…

【数据结构与算法】单向链表

一、什么是链表 链表由一系列节点组成&#xff0c;每个节点都包含一个 data 域&#xff08;存放数据&#xff09;和一个 next 域&#xff08;指向下一节点&#xff09;。链表中的节点可以按照任意顺序存放在内存中&#xff0c;它们之间并不连续。每个节点都记录了下一个节点的地…

【AI大模型系列】常用的提示词框架(二)

目录 一、ICIO框架 1.1 ICIO框架组成 1.2 ICIO框架案例 二、CRISPE框架 2.1 CRISPE框架组成 2.2 CRISPE框架案例 三、BROKE框架 3.1 BROKE框架组成 3.2 BROKE框架案例 四、RASCEF框架 4.1 RASCEF框架组成 4.2 RASCEF框架案例 一、ICIO框架 1.1 ICIO框架组成 Instru…

【Golang 面试题】每日 3 题(八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

struct udp_sock

这个struct udp_sock结构体是Linux内核网络栈中用于表示一个UDP套接字的数据结构。它继承自struct inet_sock,这意味着它包含了所有IPv4或IPv6套接字共享的基础信息和函数指针。下面是对struct udp_sock中一些关键成员的解释: struct inet_sock inet;:这是udp_sock结构体的第…