线段树求区间最值问题

引言

今天主要还是练了两道题,是有关线段树如何去求一个区间内的最值问题的,我们可以用线段树来解决。

对应一个无法改变顺序的数组,我们想要去求一个区间内的最值,假设有n个结点,m次询问,暴力的解决办法的时间复杂度为O(m*n),当结点的个数很大时,对时间的花销太大了,因此我们可以考虑用线段树来解决问题,时间复杂度仅为O(m*logn),也许仅这样看你看不出来线段树的优势,换句话说,要查一个区间长度为40亿的区间,仅需要不到33次就可以查完

因此,我们今天的主题就是如何用线段树来解决区间内的最值问题(最大值,最小值)

例题

1.求区间内的最小值

P1816 忠诚

思路:对于这种区间问题,我们在建树方面就会有所不同,我们首先在建树的时候,sum中指的不在是区间中的权值,而是区间中的最值,对于某个结点,我们的sum中存储的就是这个区间里面的最值

然后在查区间的时候也会有所不同,我们需要判断区间是否在左子树或者右子树,以及处理区间在左右子树都有重叠位置

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int num[100005];
int x,y;
struct node{
	int l;
	int r;
	int sum;
}tree[100005*4];

void build(int i,int l,int r)
{
	tree[i].l=l,tree[i].r=r;
	if(l==r)
	{
		tree[i].sum=num[l];
		return ;
	}
	int mid=(l+r)/2;
	build(i*2,l,mid);
	build(i*2+1,mid+1,r);
	tree[i].sum=min(tree[i*2].sum,tree[i*2+1].sum);//存储子树中最小的那个
	return ;
}

int find(int i,int l,int r)
{
	if(tree[i].l>=l&&tree[i].r<=r)
	{
		return tree[i].sum;
	}
	int mid=(tree[i].l+tree[i].r)/2;
	if(mid>=r)//处于左子树
	{
		return find(i*2,l,r);
	} 
	if(mid<l)//处于右子树
	{
		return find(i*2+1,l,r);
	}
	return min(find(i*2,l,mid),find(i*2+1,mid+1,r));//两边都有涉及
}

signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>num[i];
	}
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		cout<<find(1,x,y)<<" ";
	}
	return 0;
} 

2.求区间内的最大值

P1531 I Hate It

思路:很明显的单点修改的线段树的求区间最大值问题,我们在修改单点最大值的时候也要回退去修改其余相关区间内的最大值,查询和建树和上面的那个最小值差不多

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int num[200005];
char s;
int a,b;
struct node{
	int l;
	int r;
	int sum;
}tree[200005*4];

void build(int i,int l,int r)
{
	tree[i].l=l,tree[i].r=r;
	if(l==r)
	{
		tree[i].sum=num[l];
		return ;
	}
	int mid=(l+r)/2;
	build(i*2,l,mid);
	build(i*2+1,mid+1,r);
	tree[i].sum=max(tree[i*2].sum,tree[i*2+1].sum);
	return ;
}

void add(int i,int dis,int k)
{
	if(tree[i].l==tree[i].r)
	{
		tree[i].sum=k;
		return ;
	}
	int mid=(tree[i].l+tree[i].r)/2;
	if(mid>=dis)
	{
		add(i*2,dis,k);
	}
	else
	{
		add(i*2+1,dis,k);
	}
	tree[i].sum=max(tree[i*2].sum,tree[i*2+1].sum);
	return ;
}

int find(int i,int l,int r)
{
	if(tree[i].l>=l&&tree[i].r<=r)
    {
    	return tree[i].sum;
    }
    int mid=(tree[i].l+tree[i].r)/2;
    if(r<=mid)
    {
    	return find(i*2,l,r);
	}
	if(l>mid)
	{
		return find(i*2+1,l,r);
	}
	return max(find(i*2,l,mid),find(i*2+1,mid+1,r));
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>num[i];
	}
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		cin>>s;
		cin>>a>>b;
		if(s=='Q')
		{
			cout<<find(1,a,b)<<"\n";
		}
		else
		{
			if(num[a]<b)
			{
				num[a]=b;
				add(1,a,b);
			}
		}
	}
	return 0;
}

总结 

线段树去求区间最值问题,一般用于区间内的数没有顺序,不能使用二分的时候可以考虑使用线段树来求最值问题,时间复杂度在查询和修改的时候也为O(logN)可以很大节约时间开销

同时在其中建树的时候也是有讲究的,其中的sum为区间内的最值

建树代码

求区间最大值:

void build(int i,int l,int r)
{
	tree[i].l=l,tree[i].r=r;
	if(l==r)
	{
		tree[i].sum=num[l];
		return ;
	}
	int mid=(l+r)/2;
	build(i*2,l,mid);
	build(i*2+1,mid+1,r);
	tree[i].sum=max(tree[i*2].sum,tree[i*2+1].sum);
	return ;
}

求区间最小值:

void build(int i,int l,int r)
{
	tree[i].l=l,tree[i].r=r;
	if(l==r)
	{
		tree[i].sum=num[l];
		return ;
	}
	int mid=(l+r)/2;
	build(i*2,l,mid);
	build(i*2+1,mid+1,r);
	tree[i].sum=min(tree[i*2].sum,tree[i*2+1].sum);
	return ;
}

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

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

相关文章

Spring Bean生命周期

Bean生命周期&#xff1a; 创建 Bean 的实例&#xff1a;Bean 容器首先会找到配置文件中的 Bean 定义&#xff0c;然后使用 Java 反射 API 来创建 Bean 的实例。 Bean 属性赋值/填充&#xff1a;为 Bean 设置相关属性和依赖&#xff0c;例如Autowired 等注解注入的对象、Value…

怎样将word默认Microsoft Office,而不是WPS

设置——>应用——>默认应用——>选择"word"——>将doc和docx都选择Microsoft Word即可

Java-数据结构

数据结构概述 常见的数据结构 栈 队列 数组 链表 二叉树 二叉查找树 平衡二叉树 红黑树 示例&#xff1a;

电气-伺服(4)CANopen

一、CAN Controller Area Network ,控制器局域网&#xff0c;80年的德国Bosch的一家公司研发可以测量仪器直接的实时数据交换而开发的一款串行通信协议。 CAN发展历史 二、CAN 的osi 模型 CAN特性&#xff1a; CAN 的数据帧 三、CANopen 什么是CANopen CANopen 的网络模型 …

怎么用AI合成PPT?这5款风靡全球的AIPPT软件一定要知道!

当下我们已进入信息过载的时代&#xff0c;每天有无数的信息试图争夺我们的注意力&#xff0c;与此同时&#xff0c;我们也需要向别人展示和呈现信息&#xff0c;这就要求我们能够以最低的成本&#xff0c;在短时间内引起对方的注意&#xff0c;这其中最常用到的工具非PPT莫属。…

CVPR 2024最佳论文:“神兵”的组合器 Generative Image Dynamics

CVPR 2024的最佳论文来自谷歌、美国加州大学圣迭戈分校。两篇都来至于视频生成领域&#xff0c;可见今年外界对视频生成领域关注度很高。今天的这篇是“Generative Image Dynamics”&#xff0c;Google Research发布的。它的研究成果令人震惊&#xff0c;从单张RGB图像生成连续…

c语言回顾-内存操作函数

目录 前言 1.memcpy 函数 1.1函数介绍 1.2与strcpy的区别 1.3memcpy的模拟 2.memmove 函数 2.1函数介绍和使用 2.2函数的模拟 3.memset函数 3.1函数介绍 3.2函数的模拟 4.memcmp函数 4.1函数的使用 4.2函数的模拟 结束语 前言 在动态内存的章节中小编详细讲解了动…

【代码随想录】【算法训练营】【第51天】 [115]不同的子序列 [583]两个字符串的删除操作 [72]编辑距离

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 51&#xff0c;周四&#xff0c;又是不能坚持的一天~ 题目详情 [115] 不同的子序列 题目描述 115 不同的子序列 解题思路 前提&#xff1a;转换为t为s的子序列的个数&#xff0c;元素的相对…

flask项目部署总结

这个部署的时候要用虚拟环境&#xff0c;cd进项目文件夹 python3 -m venv myenv source myenv/bin/activate激活 之后就安装一些库包之类的&#xff0c;&#xff08;flask&#xff0c;requests,bs4,等等&#xff09; 最重要的是要写.flaskenv文件并且pip install 一个能运行…

【MySQL】InnoDB的存储结构

InnoDB的存储结构&#xff1a;每个表都会生成一个表空间文件&#xff0c;这个文件里面最小结构就是行&#xff0c;存储的真正的数据&#xff0c;一个页来管理若干行&#xff0c;一个区来管理若干页&#xff0c;一个区组来管理若干区。段并不是真正的物理存储结构&#xff0c;它…

计组期末复习

本内容是我在计组期末复习时的记录&#xff0c;可能对你的复习帮助不大。下面是我复习时看的一些资料和视频&#xff1a; 知识体系&#xff1a; 【【计算机组成原理】计算机组成原理期末考试速成课&#xff0c;不挂科&#xff01;&#xff01;】https://www.bilibili.com/video…

轻松跨越国界:使用WildCard畅享全球AI服务

大家好&#xff0c;现在AI技术已经深入到我们的日常生活中。然而&#xff0c;许多朋友仍然难以获取优质的AI工具和应用。那么&#xff0c;如何才能使用像ChatGPT这样的AI服务呢&#xff1f; 今天我为大家介绍一个“一劳永逸”的解决方案&#xff0c;它就是我们的主角——WildC…

spdlog一个非常好用的C++日志库(四): 源码分析之logger类

目录 1.简介 2.类图关系 3.logger数据成员 4.logger函数成员 4.1.构造与析构 4.1.1.构造函数 4.1.2.拷贝构造、移动构造 4.2.交换操作 4.3.log()记录日志消息 4.3.1.格式串 4.3.2.普通字符串 4.3.3.日志级别 4.3.4.宽字符支持 4.4.sink_it_&#xff1a;将log消息…

【内网渗透】从0到1的内网渗透基础概念笔记

目录 域 域的介绍 单域 父域和子域 域树 域森林 域名服务器 活动目录 活动目录介绍 域内权限 组 域本地组 全局组 通用组 总结 示例 A-G-DL-P策略 重要的域本地组 重要的全局组、通用组 安全域划分 域 域的介绍 Windows域是计算机网络的一种形式&#xf…

币界网讯,预计以太坊现货 ETF 将于 7 月中旬推出

刚刚 ETF Store 总裁 Nate Geraci 在 X &#xff08;前Twitter&#xff09;平台上宣布&#xff0c;备受数字货币市场期待的SEC以太坊现货 ETF提案&#xff0c;将于7 月中旬通过美国证券交易委员会&#xff08;SEC&#xff09;批准。Nate Geraci透露修订后的 S-1 文件将于 7 月 …

艺活网DIY手工制作网站源码 工艺制作教程平台源码,带数据

帝国CMS仿《手艺活》DIY手工制作网源码&#xff0c;仿手艺活自适应手机版模板。 带数据库和图片资源&#xff0c;一共5个G大小&#xff0c;下载需耐心。 92开发 手艺活网DIY手工制作网站源码 创意手工艺品制作教程平台系统帝国h5自适应手机端 是一套展示各种 DIY 小物品精美又…

初学Spring之自动装配 Bean

Bean 的作用域&#xff1a; 1.单例模式&#xff08;Spring 默认机制&#xff09; scope“singleton” 2.原型模式&#xff1a;每次从容器中 get 时&#xff0c;都会产生一个新对象 scope"prototype" 3. request、session、application&#xff0c;只能在 web 开…

webp2jpg网页在线图片格式转换源码

源码介绍 webp2jpg-免费在线图片格式转化器, 可将jpeg、jpg、png、gif、 webp、svg、ico、bmp文件转化为jpeg、png、webp、webp动画、gif文件。 无需上传文件&#xff0c;本地即可完成转换! 源码特点&#xff1a; 无需上传&#xff0c;使用浏览器自身进行转换批量转换输出we…

九、函数的声明和定义

函数声明&#xff1a; 1. 告诉编译器有一个函数叫什么&#xff0c;参数是什么&#xff0c;返回类型是什么。但是具体是不是存在&#xff0c;函数 声明决定不了。 2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。 3. 函数的声明一般要放在头文件中的。 定义的函…

视频监控平台web客户端的免密查看视频页:在PC浏览器上如何调试手机上的前端网页(PC上的手机浏览器的开发者工具)

目录 一、手机上做前端页面开发调试 1、背景 2、视频监控平台AS-V1000的视频分享页 3、调试手机前端页面代码的条件 二、手机端的准备工作 1、手机准备 2、手机的开发者模式 3、PC和手机的连接 &#xff08;1&#xff09;进入调试模式 &#xff08;2&#xff09;选择…
最新文章