洛谷 U411986 数的范围(二分模板)

题意:在一个有序序列里面找某个值的初始出现下标和最后出现下标,如果该值不存在,输出-1 -1。

整数二分模板题,该题主要用来练习如何写两种情况下的二分函数的代码模板。

1)upper_bound函数:用来寻找边界点A,即是在区间[0, A]中,所有元素都满足同一个性质的最边界。

如果我们把区间通过中间点mid=(l+r)/2来划分成两个长度一样的子区间,则下标为mid的值array[mid]计算出来的性质可能会有这两种情况:

a)值array[mid]满足绿色区间性质:

那么由图可以看出,边界点A的位置,一定在半边子区间,极端情况下,mid有可能就是边界点A。所以下一个我们要去搜索的区间范围可以缩减为:

[mid,r],l更新为mid。

注意这里mid是包含的。

b)值array[mid]不满足绿色区间性质:

那么由图可以看出,边界点A的位置,一定在半边子区间,而且mid不可能是边界点A。

所以下一个我们要去搜索的区间范围可以缩减为:

[l,mid-1],r更新为mid-1。

搜索终止的条件是l和r相等,且边界点A的解为l或者r。

代码模板如下:

int find_a(int k) {
    int l = 0, r = n-1;
    while (l < r) {
        int mid = (l + r + 1) / 2;
        if (arr[mid] <= k)
            l = mid;
        else
            r = mid -1;
    }
    return l;
}

这里注意到模板中mid的取值是(l+r+1)/2,而不是(l+r)/2,是因为mid的取值是向下取整的,当l和r只相差1时,mid=(l+r)/2就等于(2*l+1)/2=l,如果此时需要更新的是区间左端点l,那么l=mid操作一通后,l的值还是原来的值,会导致死循环。

所以把mid的值设置为(l+r+1)/2,这样分区间时还是可以视为是对半分的,还可以避免死循环。

1)lower_bound函数:用来寻找边界点B,即是在区间[B, n-1]中,所有元素都满足同一个性质的最边界。

我们用同样的方法分析两种mid存在的情况:

a)值array[mid]满足红色区间性质:

那么更新的下一个搜索区间为:[l,mid]。

b)值array[mid]不满足红色区间性质:

那么更新的下一个搜索区间为:[mid+1,r]。

代码模板如下:

int find_b(int k) {
	int l = 0, r = n-1;
	while (l < r) {
		int mid = (l + r) / 2;
		if (arr[mid] >= k)
			r = mid;
		else
			l = mid + 1;
	}
	// 找到的边界B的值就是l,也是r,因为l==r 
	return l;
}

本题AC代码如下:

#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 100010;
int arr[MAXN];
int n, q;

int find_b(int k) {
	int l = 0, r = n-1;
	while (l < r) {
		int mid = (l + r) / 2;
		if (arr[mid] >= k)
			r = mid;
		else
			l = mid + 1;
	}
	// 找到的边界B的值就是l,也是r,因为l==r 
	if (arr[l] == k)
		return l;
	return -1;
}

int find_a(int k) {
	int l = 0, r = n-1;
	while (l < r) {
		int mid = (l + r + 1) / 2;
		if (arr[mid] <= k)
			l = mid;
		else
			r = mid -1;
	}
	return l;
}

int main() {
	while (~scanf("%d%d", &n, &q)) {
		for (int i=0; i < n; i++)
			scanf("%d", arr+i);
		while (q--) {
			int k;
			scanf("%d", &k);
			int start = find_b(k), end;
			if (start == -1) {
				printf("-1 -1\n");
			} else {
				end = find_a(k);
				printf("%d %d\n", start, end);
			}
		}
	}
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙是必经之路

少了大嘴的发布会&#xff0c;老实讲有点让人昏昏入睡。关于技术本身的东西&#xff0c;放在后面。 我想想来加把油~ 鸿蒙发布后褒贬不一&#xff0c;其中很多人不太看好鸿蒙&#xff0c;一方面是开源性、一方面是南向北向的利益问题。 不说技术的领先点&#xff0c;我只扯扯…

香橙派5(RK3588)使用npu加速yolov5推理的部署过程

香橙派5使用npu加速yolov5推理的部署过程 硬件环境 部署过程 模型训练(x86主机) 在带nvidia显卡(最好)的主机上进行yolo的配置与训练, 获取最终的best.pt模型文件, 详见另一篇文档 模型转换(x86主机) 下载airockchip提供的yolov5(从pt到onnx) 一定要下这个版本的yolov5, …

【力扣 + 牛客 | SQL题 | 每日三题】大厂笔试真题W1,W4

1. 力扣603&#xff1a;连续空余的座位 1.1 题目&#xff1a; 表: Cinema ------------------- | Column Name | Type | ------------------- | seat_id | int | | free | bool | ------------------- Seat_id 是该表的自动递增主键列。 在 PostgreSQL 中&#…

练习LabVIEW第十九题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第十九题&#xff1a; 创建一个程序把另外一个VI的前面板显示在Picture控件中 开始编写&#xff1a; 在前面板放置一个二…

C语言教程——数组(2)

目录 系列文章目录 前言 4、数组作为函数参数 4.1冒泡函数的错误设计 4.2数组名是什么&#xff1f; 总结 前言 我们知道一维数组是连续存放的&#xff0c;随着数组下标的增长&#xff0c;地址是由低到高依次存放的&#xff0c;二维数组&#xff0c;也是在内存里面是连续存放的…

Linux | 配置docker环境时yum一直出错的解决方法

yum出错 Centos 7版本出错问题补充&#xff1a;什么是yumyum 和 apt 有什么区别&#xff1f; Centos 7版本 [rootlocalhost yum.repos.d]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)出错问题 问题1 Could not retrieve mirrorlist http://mirrorlist.ce…

SQLite 3.47.0 发布,大量新功能来袭

SQLite 开发团队于 2024 年 10 月 21 日发布了 SQLite 3.47.0 版本&#xff0c;我们来了解一下新版本的改进功能。 触发器增强 SQLite 3.47.0 版本开始&#xff0c;触发器函数 RAISE() 的 error-message 参数可以支持任意 SQL 表达式。在此之前&#xff0c;该参数只能是字符串…

论1+2+3+4+... = -1/12 的不同算法

我们熟知自然数全加和&#xff0c; 推导过程如下&#xff0c; 这个解法并不难&#xff0c;非常容易看懂&#xff0c;但是并不容易真正理解。正负交错和无穷项计算&#xff0c;只需要保持方程的形态&#xff0c;就可以“预知”结果。但是这到底说的是什么意思&#xff1f;比如和…

Nodejs使用pkg打包为可执行文件

安装pkg npm install -g pkg查看pkg命令 pkg --help修改package.json 新增bin入口配置 {"name": "takescreenshot","version": "1.0.0","bin": "app.js", // 新增bin入口配置"scripts": {"t…

day10:ssh服务-跳板机

一&#xff0c;ssh服务概述 ssh服务概述 ssh&#xff08;Secure Shell&#xff09;是一种用于在不安全网络中进行安全登录、远程执行命令及传输文件的网络协议。它通过加密技术来保证通信的保密性和完整性&#xff0c;主要用于替代不安全的telnet、rlogin、rsh等协议。ssh通常…

计算机视觉-边缘检测实验报告

实验一 边缘检测实验 一、实验目的 1&#xff0e;理解并掌握 Sobel 算子和 Canny 算子的基本原理和应用。 2&#xff0e;学习如何在图像处理中使用这两种算子进行边缘检测。 3&#xff0e;比较 Sobel 算子和 Canny 算子的性能&#xff0c;了解各自的优缺点。 4&#xff0…

【mysql进阶】4-3. 页结构

页面结构 ⻚在MySQL运⾏的过程中起到了⾮常重要的作⽤&#xff0c;为了能发挥更好的性能&#xff0c;可以结合⾃⼰系统的业务场景和数据⼤⼩&#xff0c;对⻚相关的系统变量进⾏调整&#xff0c;⻚的⼤⼩就是⼀个⾮常重要的调整项。同时关于⻚的结构也要有所了解&#xff0c;以…

HTTP协议讲解

前瞻&#xff1a; 认识URL 1.ipport 2.平时上网&#xff0c;就是进程间通信 3.上网行为&#xff0c;1.获取资源 2.上传数据 相当于I/O 4.http协议采用tcp协议 网页 图片 音乐其实都是资源 Http请求 http request Method&#xff1a;Get/Post资源/路径&#xff1a…

MyBatis缓存详解(一级缓存、二级缓存、缓存查询顺序)

固态硬盘缺陷&#xff1a;无法长时间使用&#xff0c;而磁盘只要不消磁&#xff0c;只要不受到磁影响&#xff0c;就可以长期使用&#xff0c;因此绝大多数企业还是使用磁盘来存储数据 像mysql这种关系型数据库中的数据存储在磁盘中&#xff0c;为方便查询&#xff0c;减少系统…

Linux文件类型和根目录结构

Linux文件类型和根目录结构 1.文件类型 字符文件类型说明~普通文件类似于Windows的记事本d目录文件类似于windows文件夹c字符设备文件串行端口设备&#xff0c;顺序读写&#xff0c;键盘b块设备文件可供存储的接口设备&#xff0c;随机读写&#xff0c;硬盘p管道文件用于进程…

工程项目管理软件怎么选?推荐7款实用工具

本文提及的有主流7款工程项目管理系统软件有: 1. Worktile&#xff1b;2. 广联达BIM5D&#xff1b;3. 泛普软件&#xff1b;4. 明源云工程&#xff1b;5. 飞书&#xff1b;6. Smartsheet&#xff1b;7. Procore。 很多工程项目管理人员常常头疼如何有效地管理多个项目&#xff…

保研考研机试攻略:python笔记(1)

&#x1f428;&#x1f428;&#x1f428;宝子们好呀 ~ 我来更新欠大家的python笔记了&#xff0c;从这一篇开始我们来学下python&#xff0c;当然&#xff0c;如果只是想应对机试并且应试语言以C和C为主&#xff0c;那么大家对python了解一点就好&#xff0c;重点可以看高分篇…

【机器学习】——numpy教程

文章目录 1.numpy简介2.初始化numpy3.ndarry的使用3.1numpy的属性3.2numpy的形状3.3ndarray的类型 4numpy生成数组的方法4.1生成0和1数组4.2从现有的数组生成4.3生成固定范围的数组4.4生成随机数组 5.数组的索引、切片6.数组的形状修改7.数组的类型修改8.数组的去重9.ndarray的…

接口测试(七)jmeter——参数化(RandomString函数)

一、RandomString函数 需求&#xff1a;模拟10个用户注册 1. 【工具】–>【函数助手对话框】 2. 选择RandomString函数 假设手机号码前3位设置为固定数值136&#xff0c;后8位可用RandomString函数随机产生数值 ① Random string length&#xff1a;8&#xff08;随机长度…