高级数据结构—线段树(一)

news2024/10/7 8:19:40

学线段树的原因是因为cf的一道题目始终想不出来怎么优化,后来知道区间查询和修改要用到线段树。。。

原题:Iva & Pav

线段树的作用

  1. 区间最值查询:可以高效地找到给定区间内的最大值、最小值等。

  2. 区间和查询:可以高效地计算给定区间内元素的和、积等。

  3. 区间更新:可以高效地对给定区间内的元素进行更新操作,如增加一个固定值、赋值等。

  4. 区间覆盖:可以将给定区间内的元素全部赋值为一个固定值。

  5. 区间合并:可以将多个区间合并成一个区间,快速地进行区间合并操作。

  6. 区间离散化:可以将区间内的元素进行离散化处理,方便进行查询和统计操作。

  7. 区间交集:可以快速地找到多个区间之间的交集

线段树和树状数组的区别 

 刚学完树状数组来学线段树,一开始还不知道他们具体的差别在哪里,那么以下是我的理解。

1.树状数组是前缀和优化,要用到前缀和的时候较为方便。

2.树状数组用来进行单点修改,区间查询;或者区间修改,单点查询较为方便,而区间查询和区间修改较为复杂,因此可以用线段树优化。

3.线段树适用于需要频繁的区间查询和更新操作的问题,如区间最值、区间和等,能够灵活处理各种区间操作。

4.树状数组适用于一维数组的前缀和查询和更新操作,对于简单的区间操作也能够提供高效的解决方案。

例题: 

最大数

题目链接:最大数

直接看代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
//单点插入,区间查询
const int N = 2e5+5;
struct node{
	int l,r;
	int v;
}tr[N*4];

int m,p;

//子节点的信息更新父节点
void pushup(int u){
	tr[u].v=max(tr[u<<1].v,tr[u<<1|1].v);
}

//u为当前线段树节点编号
void build(int u,int l,int r){
	tr[u]={l,r};
	if(l==r)return;
	int mid=l+r>>1;
	build(u<<1,l,mid);
	build(u<<1|1,mid+1,r);
}

//查询以u为根节点,区间[l,r]中的最大值
int query(int u, int l, int r) {
    //      Tl-----Tr
    //   L-------------R   
    //1.不必分治,直接返回
    if(tr[u].l >= l && tr[u].r <= r) return tr[u].v;

    int mid = tr[u].l + tr[u].r >> 1;
    int v = 0;
    //     Tl----m----Tr
    //        L-------------R 
    //2.需要在tr的左区间[Tl, m]继续分治
    if(l <= mid) v = query(u << 1, l, r);

    //     Tl----m----Tr
    //   L---------R 
    //3.需要在tr的右区间(m, Tr]继续分治
    if(r > mid) v = max(v, query(u << 1 | 1, l, r));

    //     Tl----m----Tr
    //        L-----R 
    //2.3涵盖了这种情况
    return v;
}

//u为节点编号,x为修改位置,v为修改的值
void modify(int u,int x,int v){
	if(tr[u].l==tr[u].r)tr[u].v=v;//叶子节点,递归出口
	else{
		int mid=tr[u].l+tr[u].r>>1;
		//分治,修改位置偏左往左边遍历,偏右往右边遍历
		if(x<=mid)modify(u<<1,x,v);
		else {
			modify(u<<1|1,x,v);
		}
		pushup(u);//回溯,子节点的信息更新父节点
	}
}

signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	//n表示树中节点个数,last表示上一次查询的结果
	int n=0,last=0;
	cin>>m>>p;

	//初始化线段树,节点的区间最多为[1,m]
	build(1,1,m);

	while(m--){
		char op;cin>>op;
		if(op=='A'){//添加节点
			int t;cin>>t;
			//在n+1处插入
			modify(1,n+1,(t+last)%p);
			//节点个数+1
			n++;
		}
		else {
			int l;cin>>l;
			//查询[n - L + 1, n]内的最大值,u = 1,即从根节点开始查询
			last=query(1,n-l+1,n);
			cout<<last<<"\n";
		}
	}

	return 0;
}

你能回答这些问题吗

题目链接:你能回答这些问题吗

如图:

如图,假设我们要求区间的最大子段和,有三种情况:

1.包含所有左半边,部分右半边----->左半边的区间和+右半边的前缀和

2.包含所有右半边,部分左半边----->右半边的区间和+左半边的后缀和

3.中间的一部分----->左半边的后缀和+右半边的前缀和

因此我们的结构体要记录四个信息:

struct node{
	int l,r;
	int sum;//[l,r]的区间和
	int lmax;//最大前缀和
	int rmax;//最大后缀和
	int tmax;//区间[l,r]最大连续子段和
}tr[N*4];

 同时pushup函数根据上图可以推出:(重载函数)

//u表示该节点,l表示该节点的左子树,r表示该节点的右子树
void pushup(node &u,node &l,node &r){
	u.sum=l.sum+r.sum;
	//三种最大连续子段和的情况
	u.lmax=max(l.lmax,l.sum+r.lmax);
	u.rmax=max(r.rmax,r.sum+l.rmax);
	u.tmax=max({l.tmax,r.tmax,l.rmax+r.lmax});
}

void pushup(int u){
	pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}

代码附上:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e5+5;
int w[N];
int n,m;
struct node{
	int l,r;
	int sum;//[l,r]的区间和
	int lmax;//最大前缀和
	int rmax;//最大后缀和
	int tmax;//区间[l,r]最大连续子段和
}tr[N*4];

//u表示该节点,l表示该节点的左子树,r表示该节点的右子树
void pushup(node &u,node &l,node &r){
	u.sum=l.sum+r.sum;
	//三种最大连续子段和的情况
	u.lmax=max(l.lmax,l.sum+r.lmax);
	u.rmax=max(r.rmax,r.sum+l.rmax);
	u.tmax=max({l.tmax,r.tmax,l.rmax+r.lmax});
}

void pushup(int u){
	pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}

void build(int u,int l,int r){
	if(l==r)tr[u]={l,r,w[r],w[r],w[r],w[r]};//找到叶子节点
	else{
		tr[u]={l,r};//设当前区间为[l,r]
		int mid=l+r>>1;
		build(u<<1,l,mid);//左子树
		build(u<<1|1,mid+1,r);//右子树
		pushup(u);//修改父节点
	}
}

//每次从1号节点开始找,找到位置位于x的数,并把它修改为v
void modify(int u,int x,int v){
	if(tr[u].l==x && tr[u].r==x)tr[u]={x,x,v,v,v,v};
	else{
		int mid=tr[u].l+tr[u].r>>1;
		if(x<=mid)modify(u<<1,x,v);//x位于当前区间的左半子区间
		else modify(u<<1|1,x,v);//x位于当前区间的右半子区间
		pushup(u);//修改父节点的相关信息
	}
}

node query(int u,int l,int r){
	if(tr[u].l>=l&&tr[u].r<=r)return tr[u];//被包含
	else{
		int mid=tr[u].l+tr[u].r>>1;
		if(r<=mid)return query(u<<1,l,r);//查询左半区间
		else if(l>mid)return query(u<<1|1,l,r);//查询右半区间
		else{//横跨左右区间
			auto left=query(u<<1,l,r);
			auto right=query(u<<1|1,l,r);
			node res;
			pushup(res,left,right);
			return res;
		}
	}
}

signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>w[i];
	build(1,1,n);//建树

	int k,x,y;
	while(m--){
		cin>>k>>x>>y;
		if(k==1){//查询
			if(x>y)swap(x,y);
			cout<<query(1,x,y).tmax<<"\n";
		}
		else modify(1,x,y);//修改
	}

	return 0;
}

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

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

相关文章

小程序AI智能名片S2B2C商城系统:解锁内容深耕新境界,助力品牌企业高效定制内容策略

在数字化时代&#xff0c;内容营销已成为品牌企业获取市场份额、增强用户黏性的关键武器。然而&#xff0c;面对海量的互联网信息和复杂多样的社交媒体平台&#xff0c;如何有效地深耕内容&#xff0c;成为众多品牌企业面临的难题。 传统的内容分类与识别方式&#xff0c;往往依…

信息系统项目管理师0066:过程管理(5信息系统工程—5.1软件工程—5.1.6过程管理)

点击查看专栏目录 文章目录 5.1.6过程管理1.成熟度模型2.成熟度等级5.1.6过程管理 软件过程能力是组织基于软件过程、技术、资源和人员能力达成业务目标的综合能力。包括治理能力、开发与交付能力、管理与支持能力、组织管理能力等方面。软件过程能力成熟度是指组织在提升软件产…

明日方舟游戏助手:一键完成日常任务 | 开源日报 No.233

MaaAssistantArknights/MaaAssistantArknights Stars: 11.6k License: AGPL-3.0 MaaAssistantArknights 是一款《明日方舟》游戏的小助手&#xff0c;基于图像识别技术&#xff0c;支持一键完成全部日常任务。 刷理智、掉落识别及上传企鹅物流智能基建换班、自动计算干员效率…

Day 20 Linux的WEB服务——apache

WEB服务简介 目前主流的web服务器软件 Linux&#xff1a;apache &#xff0c; nginx Windows-server&#xff1a;IIS 服务器安装nginx或apache后&#xff0c;叫做web服务器&#xff08;又称WWW服务器&#xff09; web服务器软件属于C/S框架模型 web服务器是一种被动程序只…

jmeter之连接MySQL数据库

jmeter连接mysql数据库 mysql官网下载地址&#xff1a;MySQL :: Download Connector/J 步骤如下&#xff1a; 1、下载mysql的jar包放入到jmeter的lib/ext下&#xff0c;然后重启jmeter 链接: https://pan.baidu.com/s/1rRrMQKnEuKz8zOUfMdMHFg?pwdawfc 提取码: awfc 2、配置…

如何解决升级IntelliJ IDEA 2024后 打开项目就自动闪退关闭问题的终极指南

title: “&#x1f42f; 解决升级IntelliJ IDEA 2024后项目自动关闭的终极指南” date: 2024-04-23 author: 猫头虎 profile: CSDN 文章目录 title: "&#x1f42f; 解决升级IntelliJ IDEA 2024后项目自动关闭的终极指南" date: 2024-04-23 author: 猫头虎 profile: …

STM32点灯大师(中断法)

一、使用CubeMX配置 新增加了RCC进行配置 二、代码 需要重写虚函数&#xff0c;给自己引用

2024深圳杯数学建模挑战赛B题:批量工件并行切割下料问题思路代码成品论文分析

更新完整代码和成品完整论文 《2024深圳杯&东三省数学建模思路代码成品论文》↓↓↓ https://www.yuque.com/u42168770/qv6z0d/zx70edxvbv7rheu7?singleDoc# 问题重述 深圳杯数学建模挑战赛2024B题&#xff1a;批量工件并行切割下料问题 板材切割下料是工程机械领域重要…

盲人过马路安全:科技力量赋予“隐形守护者”

作为一名资深记者&#xff0c;我始终关注着社会各群体的生活现状&#xff0c;尤其是那些面临特殊挑战的人群。今天&#xff0c;我想聚焦一个看似平常却对盲人构成重大困扰的日常场景——过马路&#xff0c;以及一款名为蝙蝠避障的辅助应用如何成为他们的盲人过马路安全的守护者…

springboot的坑

问题&#xff1a;使用Autowired注入一个service&#xff0c;然后写了两个接口&#xff0c;第一个接口与请求时显示注入的service为空一直报错&#xff0c;但是第二个接口请求时service竟然不是空&#xff1f;在这里插入图片描述 凶手找到了&#xff0c;是private修饰。果然没仔…

CDN、边缘计算与云计算:构建现代网络的核心技术

在数字化时代&#xff0c;数据的快速传输和处理是保持竞争力的关键。内容分发网络&#xff08;CDN&#xff09;、边缘计算和云计算共同构成了现代互联网基础架构的核心&#xff0c;使内容快速、安全地到达用户手中。本文将探讨这三种技术的功能、相互关系以及未来的发展趋势。 …

网络 (基础概念, OSI 七层模型, TCP/IP 五层模型)

网络互连 网络互连: 将多台计算机连接在一起, 完成数据共享 数据共享的本质是网络数据传输, 即计算机之间通过网络来传输数, 也叫做网络通信 根据网络互连的规模不同, 将网络划分为局域网和广域网 注意: 局域网和广域网是相对的概念 局域网LAN 又称内网, 局域网和局域网之间在没…

CCS项目持续集成

​ 因工作需要&#xff0c;用户提出希望可以做ccs项目的持续集成&#xff0c;及代码提交后能够自动编译并提交到svn。调研过jenkins之后发现重新手写更有性价比&#xff0c;所以肝了几晚终于搞出来了&#xff0c;现在分享出来。 ​ 先交代背景&#xff1a; 1. 代码分两部分&am…

谷粒商城实战(017 业务-单点登录)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第231p-第p235的内容 介绍 单点登录&#xff08;Single Sign-On&#xff0c;SSO&#xff09;是一种身份验证服务&#xff0c;允许用户使用一组凭…

程序猿成长之路之数据挖掘篇——朴素贝叶斯

朴素贝叶斯是数据挖掘分类的基础&#xff0c;本篇文章将介绍一下朴素贝叶斯算法 情景再现 以挑选西瓜为例&#xff0c;西瓜的色泽、瓜蒂、敲响声音、触感、脐部等特征都会影响到西瓜的好坏。那么我们怎么样可以挑选出一个好的西瓜呢&#xff1f; 分析过程 既然挑选西瓜有多个…

【七】jmeter5.5+influxdb2.0+prometheus+grafana

参考文章&#xff1a;https://blog.csdn.net/wenxingchen/article/details/126892890 https://blog.csdn.net/Zuo19960127/article/details/119726652 https://blog.csdn.net/shnu_cdk/article/details/132182858 promethus参考 由于自己下载的是infuldb2.0&#xff0c;所以按照…

【视频异常检测】Open-Vocabulary Video Anomaly Detection 论文阅读

Open-Vocabulary Video Anomaly Detection 论文阅读 AbstractMethod3.1. Overall Framework3.2. Temporal Adapter Module3.3. Semantic Knowledge Injection Module3.4. Novel Anomaly Synthesis Module3.5. Objective Functions3.5.1 Training stage without pseudo anomaly …

【webrtc】Chrome和Firefox在SDP协商过程中,针对localhost的不同处理

内网下chrome端webrtc协商失败 现象 我有一个webrtc服务器在局域网内&#xff0c;使用chrome浏览器访问时&#xff0c;发现webrtc在做媒体协商时失败。 具体表现是&#xff0c;在交换sdp后&#xff0c;ice的状态是oniceconnectionstatechange: failed 但是换成Firefox浏览器…

【Linux】文件目录及路径表示

1. Linux目录结构 在 Linux 系统中&#xff0c;有几个目录是比较重要的&#xff0c;平时需要注意不要误删除或者随意更改内部文件。 /etc&#xff1a; 这个是系统中的配置文件&#xff0c;如果更改了该目录下的某个文件可能会导致系统不能启动。 /bin, /sbin, /usr/bin, /usr…

黄金行情下跌有投资机会吗?

尽管黄金价格的波动常常引起投资者的高度关注&#xff0c;但行情的下跌未必只是警讯&#xff0c;亦可能蕴藏着某些难得的投资机会。总之&#xff0c;答案是肯定的——在黄金行情下跌时&#xff0c;依旧有适宜的投资机会&#xff0c;只是这需要投资者具备相应的应对知识和策略。…