线段树求区间最值问题

news2024/7/7 17:24:41

引言

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

对应一个无法改变顺序的数组,我们想要去求一个区间内的最值,假设有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.coloradmin.cn/o/1894459.html

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

相关文章

【高校科研前沿】南京地理与湖泊研究所博士后夏凡为第一作者在环境科学与水资源领域Top期刊发文:钙对云南洱海溶解有机质与浮游细菌相互作用的调控作用

文章简介 论文名称&#xff1a;Calcium regulates the interactions between dissolved organic matter and planktonic bacteria in Erhai Lake, Yunnan Province, China 第一作者及单位&#xff1a;夏凡&#xff08;博士后|中国科学院南京地理与湖泊研究所&#xff09; 通讯…

关于虚拟机CentOS 7使用ssh无法连接(详细)

虚拟机CentOS 7使用ssh无法连接 猜测&#xff1a;可能是虚拟机软件的网关和和centos7的网关不同导致的问题。 首先打开CentOS7的终端, 输入ifconfig&#xff0c;查看一下系统的ip 打开虚拟机的虚拟网络编辑器, 查看一下网关, 发现确实不一样. 这里有两种方式, 要么修改虚…

fluwx插件实现微信支付

Flutter开发使用fluwx插件实现微信支付&#xff0c;代码量不多&#xff0c;复杂的是安卓和iOS的各种配置。 在 pubspec.yaml 文件中添加fluwx依赖 fluwx: ^4.5.5 使用方法 通过fluwx注册微信Api await Fluwx().registerApi(appId: wxea7a1c53d9e5849d, universalLink: htt…

Android系统集成和使用FFmpeg

文章目录 前言FFmpeg源码下载交叉编译NDK下载x264编译源码下载编译 FFmpeg编译脚本 AOSP继承FFmpeg 前言 原生AOSP中并未继承FFmpeg&#xff0c;所以要想在android上使用&#xff0c;需要自己编译集成。 FFmpeg源码下载 git clone https://git.ffmpeg.org/ffmpeg.git目前最新…

Java [ 基础 ] Stream流 ✨

✨探索Java基础Stream流✨ 在现代Java编程中&#xff0c;Stream是一个非常强大的工具&#xff0c;它提供了一种更高效和简洁的方式来处理集合数据。在这篇博客中&#xff0c;我们将深入探讨Java中的Stream流&#xff0c;介绍它的基础知识、常见操作和一些实用示例。 什么是Str…

暗潮短视频:成都柏煜文化传媒有限公司

暗潮短视频&#xff1a;涌动的新媒体力量 在数字化时代的浪潮中&#xff0c;短视频以其独特的魅力和无限的潜力&#xff0c;迅速成为新媒体领域的一股强大力量。而在这片繁荣的短视频领域中&#xff0c;成都柏煜文化传媒有限公司“暗潮短视频”以其独特的定位和深邃的内容&…

解决mysql数据库连接报错:Authentication plugin ‘caching_sha2_password‘ cannot be loaded

解决mysql数据库连接报错&#xff1a;Authentication plugin ‘caching_sha2_password’ cannot be loaded OperationalError: (2059, “Authentication plugin ‘caching_sha2_password’ cannot be loaded: /usr/lib/mysql/plugin/caching_sha2_password.so: cannot open sha…

虚拟机与主机的联通

本地光纤分配地址给路由器--》连结路由器是连结局域网--》由路由器分配IP地址 因此在网站上搜索的IP与本机的IP是不一样的 1.windows查看主机IP地址 在终端输入 2.linux虚拟机查看ip 3.主机是否联通虚拟机ping加ip

【AI学习】无线AI的问题和挑战

无线AI&#xff0c;即无线人工智能&#xff0c;是指内生于未来&#xff08;6G&#xff09;无线通信系统并通过无线架构、无线数据、无线算法和无线应用所呈现出来的新的人工智能技术体系。 最近一直在进行无线AI的调研&#xff0c;感觉真的是路漫漫其修远兮。业界有一些探索&a…

数学建模------Matlab数据可视化

目录 1.plot函数 &#xff08;1&#xff09;函数介绍 &#xff08;2&#xff09;参数介绍 &#xff08;3&#xff09;图形美化 &#xff08;4&#xff09;背景更改 &#xff08;5&#xff09;多组绘制 &#xff08;6&#xff09;图形叠加 &#xff08;7&#xff09;添加…

Matplotlib 简介

import matplotlib.pyplot as plt plt.plot([1, 2, 3, 4]) plt.ylabel(some numbers) plt.show() 当使用plot只传入单个数组时&#xff0c;matplotlib会认为这是y的值&#xff0c;并自动生成长度相同&#xff0c;但是从0开始的x值&#xff0c;所以这里的x会自动生成为 [0,1,2,…

Vue.js 案例——商品管理

一.需要做出的效果图&#xff1a; 二.实现的步骤 首先&#xff0c;先建一个项目&#xff0c;命名Table&#xff0c;在Table项目中的components里新建一个MyTable.vue文件。 第二步&#xff0c;在原有的 HelloWorld.vue中写入代码。 HelloWorld.vue代码如下&#xff1a; <…

土地规划与文化遗产保护:在发展浪潮中守护历史的脉络

在这个日新月异的时代&#xff0c;城市化进程如火如荼&#xff0c;土地规划作为引导城市发展方向的关键&#xff0c;承载着平衡发展与保护的重任。在追求现代化的同时&#xff0c;保护文化遗产不仅是对过去的尊重&#xff0c;更是对未来负责。本文旨在深入探讨如何在土地规划实…

云桌面运维工程师

一 深信服驻场工程师 1 深信服AC、AF、AD、NGAF、WOC Atrust、WAF项目实施经验者优先考虑。 负责云桌面POC测试 部署和配置&#xff1a;设置云桌面基础设施&#xff0c;包括虚拟化平台、云桌面管理软件和相关组件。确保正确配置网络、存储和安全设置。 用户体验&#xff1…

7.3数据库第一次作业

安装MySQL 1.打开安装包 2.选择自定义安装&#xff08;custom&#xff09;并点击下一步 3.自定义安装路径 4.点击执行 5.执行成功 6.默认选项点击下一步 7.选择新的授权方式并点击下一步 8.配置密码 9.默认配置并点击下一步 10.点击执行&#xff08;Execute&#xff09; 11.执…

bcc python开发示例

文章目录 1. hello_world.py2. hello_fields.py3. sync_timing.py4. disksnoop.py5. hello_perf_output.py6. bitehist.py7. vfsreadlat.py8. urandomread.py9. strlen_count.py10. nodejs_http_server.py11. task_switch.c12. 监视 do_execve 1. hello_world.py from bcc imp…

Ubuntu 24.04-自动安装-Nvidia驱动

教程 但在安全启动模式下可能会报错。 先在Nvidia官网找到GPU对应的驱动版&#xff0c; 1. 在软件与更新中选择合适的驱动 2. ubuntu自动安装驱动 sudo ubuntu-drivers autoinstall显示驱动 ubuntu-drivers devices3. 安装你想要的驱动 sudo apt install nvidia-driver-ve…

React@16.x(48)路由v5.x(13)源码(5)- 实现 Switch

目录 1&#xff0c;原生 Switch 的渲染内容2&#xff0c;实现 1&#xff0c;原生 Switch 的渲染内容 对如下代码来说&#xff1a; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; function News() {return <div className"p…

Qt界面中的子窗口实现鼠标拖动边缘改变大小以及移动(完整demo代码)

目录 效果 拖拽 移动​编辑 实现 DragResizeWgt类.h文件 DragResizeWgt类.cpp文件 使用 testwidget窗口.ui文件 testwidget窗口.h文件 testwidget窗口.cpp文件 参考 效果 想要的效果就是类似于QT IDE中的效果&#xff0c;可以拖动边缘改变大小&#xff0c;用户自身可…

传承与创新,想让认字更简单?就来看《米小圈动画汉字》吧!

汉字&#xff0c;作为中华文化的精髓和根基&#xff0c;自古以来便承载着中华民族的思想与记忆。在现代社会&#xff0c;随着文化多样性的崛起和科技进步的推动&#xff0c;汉字的教育也更加的多元化&#xff0c;《米小圈动画汉字》作为一项全新的教育资源&#xff0c;不仅致力…