备战蓝桥杯---线段树基础1

引入:RMQ问题:

什么是RMQ?

显然,我们无法用前缀维护,因此,我们需要用到线段树的知识:

什么是线段树?

线段树是用一种树状结构存储一个连续区间信息的数据结构

下面我们用图解释用它来查询2--5信息的方式:

由此,我们可以得到几点性质:

1.他是一个平衡的二叉树。

2.对于任意两个节点,要么完全包含,要么互不相交。

3.任意的线段[a,b]在查询过程中最多分为log(b-a)个。

4.除建树外为logn.

我们来一道模板题试试水:

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,a[100000];
int tree[4*100000];
void build(int p,int l,int r){
	if(l==r){
		tree[p]=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	tree[p]=tree[p*2+1]+tree[p*2];
	return;
}
void change(int p,int l,int r,int pos,int num){
	if(l==r){
		tree[p]+=num;
		return;
	}
	int mid=(l+r)/2;
	if(pos<=mid) change(p*2,l,mid,pos,num);
	else change(p*2+1,mid+1,r,pos,num);
	tree[p]=tree[2*p]+tree[2*p+1];
	return;
}
int calc(int p,int l,int r,int x,int y){
	if(l>=x&&r<=y){
		return tree[p];
	}
	int mid=(l+r)/2;
	if(y<=mid) return calc(p*2,l,mid,x,y);
	if(x>mid) return calc(p*2+1,mid+1,r,x,y);
	return calc(p*2,l,mid,x,mid)+calc(p*2+1,mid+1,r,mid+1,y);
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	for(int i=1;i<=n;i++){
		int x,y,z;
		cin>>x>>y>>z;
		if(x==1){
			change(1,1,n,y,z);
		}
		else cout<<calc(1,1,n,y,z);
	} 
} 

让我们来看看它的实际应用吧:

区间和问题之懒标记:

我们维护一下节点的两个信息:

1.sum[i]第i个节点对应的区间和。

2.add[i]第i个节点对应区间整体加上的值并且没有同步给儿子。

这里我们就知道了为什么叫lazy,该标记仅当被标记的区间有部分被更改才顺路把标记下放给它的儿子。这样就可以减少修改的次数了。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[100010],m;
int tree[4*100010];
int lazy[4*100010];
void build(int p,int l,int r){//建树 
	if(l==r){
		tree[p]=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	tree[p]=tree[p*2+1]+tree[p*2];
	return;
}
void pushdown(int p,int l,int r){//lazy标记下移 
	int mid=(l+r)/2;
	lazy[p*2]+=lazy[p];
	lazy[p*2+1]+=lazy[p];
	tree[p*2]+=lazy[p]*(mid-l+1);//更新子节点的值 
	tree[p*2+1]+=lazy[p]*(r-mid);
	lazy[p]=0;//自己因为下移清0 
}
void change(int p,int l,int r,int x,int y,int num){
	if(x<=l&&r<=y){
		tree[p]+=num*(r-l+1);
		lazy[p]+=num;
		return;
	}
	if(lazy[p]!=0){//区间部分修改,需要下移 
		pushdown(p,l,r);
	}
	int mid=(l+r)/2;
	if(y<=mid) change(p*2,l,mid,x,y,num);
	if(x>mid) change(p*2+1,mid+1,r,x,y,num);
	if(x<=mid&&y>mid){
	change(p*2,l,mid,x,mid,num);
	change(p*2+1,mid+1,r,mid+1,y,num);}
	tree[p]=tree[2*p]+tree[2*p+1];
	return;
}
int calc(int p,int l,int r,int x,int y){
	if(l>=x&&r<=y){
		return tree[p];
	}
	if(lazy[p]!=0){
		pushdown(p,l,r);
	}
	int mid=(l+r)/2;
	if(y<=mid) return calc(p*2,l,mid,x,y);
	if(x>mid) return calc(p*2+1,mid+1,r,x,y);
	return calc(p*2,l,mid,x,mid)+calc(p*2+1,mid+1,r,mid+1,y);
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int x,y,k,op;
		scanf("%lld%lld%lld",&op,&x,&y);
		if(op==1){
			scanf("%lld",&k);
			change(1,1,n,x,y,k);
		}
		else cout<<calc(1,1,n,x,y)<<endl;
	} 
} 

区间平方和问题:

我们还是用lazy标记,不过这时我们维护的sum应该是平方和。那么我们如何维护呢?

\sum (ai+k)^2=\sum ai^2+2k\sum ai+\sum k^2

因此我们只要维护ai的前缀和即可。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[100010],m,sum[4*100010];
int tree[4*100010];
int lazy[4*100010];
void pushdown(int p,int l,int r);
int calc(int p,int l,int r,int x,int y,int k);
void build(int p,int l,int r){//建树 
	if(l==r){
		tree[p]=a[l]*a[l];
		sum[p]=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	tree[p]=tree[p*2+1]+tree[p*2];
	sum[p]=sum[p*2+1]+sum[p*2+1];
	return;
}
void pushdown(int p,int l,int r){//lazy标记下移 
	int mid=(l+r)/2;
	lazy[p*2]+=lazy[p];
	lazy[p*2+1]+=lazy[p];
	tree[p*2]+=2*lazy[p]*(sum[2*p])+lazy[p]*lazy[p]*(mid-l+1);//更新子节点的值 
	tree[p*2+1]+=2*lazy[p]*(sum[2*p+1])+lazy[p]*lazy[p]*(r-mid);
	sum[p*2]+=lazy[p]*(mid-l+1);
	sum[p*2+1]+=lazy[p]*(r-mid);
	lazy[p]=0;//自己因为下移清0 
}
void change(int p,int l,int r,int x,int y,int num){
	if(x<=l&&r<=y){
		tree[p]+=2*num*(sum[p])+num*num*(r-l+1);
		sum[p]+=num*(r-l+1);
		lazy[p]+=num;
		return;
	}
	if(lazy[p]!=0){//区间部分修改,需要下移 
		pushdown(p,l,r);
	}
	int mid=(l+r)/2;
	if(y<=mid) change(p*2,l,mid,x,y,num);
	if(x>mid) change(p*2+1,mid+1,r,x,y,num);
	if(x<=mid&&y>mid){
	change(p*2,l,mid,x,mid,num);
	change(p*2+1,mid+1,r,mid+1,y,num);}
	tree[p]=tree[2*p]+tree[2*p+1];
	sum[p]=sum[2*p]+sum[2*p+1];
	return;
}
int calc(int p,int l,int r,int x,int y,int k){
	if(l>=x&&r<=y){
		if(k==1) return tree[p];
		else return sum[p];
	}
	if(lazy[p]!=0){
		pushdown(p,l,r);
	}
	int mid=(l+r)/2;
	if(y<=mid) return calc(p*2,l,mid,x,y,k);
	if(x>mid) return calc(p*2+1,mid+1,r,x,y,k);
    return calc(p*2,l,mid,x,mid,k)+calc(p*2+1,mid+1,r,mid+1,y,k);
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int x,y,k,op;
		scanf("%lld%lld%lld",&op,&x,&y);
		if(op==1){
			scanf("%lld",&k);
			change(1,1,n,x,y,k);
		}
		else cout<<calc(1,1,n,x,y,1)<<endl;
	} 
} 

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

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

相关文章

ARM简介

ARM&#xff1a;ARM是Advanced RISC Machine的缩写&#xff0c;意为高级精简指令集计算机。 英国ARM公司&#xff0c;2016年被软银创始人孙正义斥资320亿美元收购了。现在是软银旗下的芯片设计公司&#xff0c;总部位于英国剑桥&#xff0c;专注于设计芯片&#xff0c;卖芯片生…

两台电脑异地怎么共享文件?

在现代社会中&#xff0c;无论是个人用户还是企事业单位&#xff0c;都经常面临着跨地域的文件共享需求。由于各种限制和条件的限制&#xff0c;如网络环境、设备限制等&#xff0c;可能导致文件共享变得非常困难。本文将介绍一款名为【天联】的组网产品&#xff0c;通过它可以…

非阻塞实现高效键盘扫描功能(STM32F4XX)

目录 概述 1 原理分析 1.1 技术背景 1.2 系统硬件 1.3 STM32 IO&#xff08;输入模式&#xff09;寄存器分析 1.3.1 输入IO的功能描述 1.3.2 输入配置 1.3.3 GPIO 寄存器&#xff08;输入模式相关&#xff09; 1.3.3.1 GPIO 端口模式寄存器 1.3.3.2 GPIO 端口上拉/下拉…

数字后端——DEF文件格式

文章目录 MACRO的不同orientationDEF中在macro orientation定义前需要留空格 MACRO的不同orientation DEF中在macro orientation定义前需要留空格 像下图中这种方向和分号之间没有空格的情况&#xff0c;就是有问题的格式。

构建一个基于Node.js的文件存储服务

随着现代web应用程序变得越来越复杂和功能强大&#xff0c;文件存储服务成为了许多应用的重要组成部分。在本篇博客中&#xff0c;我们将探讨如何构建一个基于Node.js的文件存储服务&#xff0c;让您可以轻松地上传、下载和管理文件。我们将利用Node.js的强大功能和模块来构建这…

苍穹外卖知识点总结(一)

简介 技术选型 展示项目中使用到的技术框架和中间件。 用户层&#xff1a;node.js Vue.js ElementUI 微信小程序 apache echarts 网关层&#xff1a;nginx 应用层&#xff1a;Spring Boot Spring MVC Spring Task httpclie…

2.26 Qt day4+5 纯净窗口移动+绘画事件+Qt实现TCP连接服务+Qt实现连接数据库

思维导图 Qt实现TCP连接 服务器端&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTcpServer>//服务器端类 #include<QTcpSocket>//客户端类 #include<QMessageBox>//消息对话框类 #include<QList>//链…

fordeal测评养号环境搭建:解决硬件、IP、浏览器等关键问题

Fordeal电商平台销售网点覆盖中东、欧美等多个国家和地区&#xff0c;其中中东市场是最重要的市场。 Fordeal主要为用户提供男女装、箱包及配饰、护肤彩妆、电子数码、运动用品等品类。 fordeal 支持多种语言、货币和支付方式。 1.点击Sign in进入登录界面。 2. 选择Register注…

第七篇:微信小程序的跳转页面

前提&#xff1a;建议还没学HTML、CSS、JavaScript、JSON、vue、Ajax的兄弟姐妹们&#xff0c;先去把这些基础补好过一遍&#xff0c;不然不好理解微信小程序 前面这一篇已经讲过一次<navigator>跳转页面的用法了&#xff0c;今天详细讲解一下 回顾&#xff1a; 小程序…

<网络安全>《60 概念讲解<第七课 网络模型OSI对应协议>》

1 OSI模型 OSI模型&#xff08;Open Systems Interconnection Model&#xff09;是一个由国际标准化组织&#xff08;ISO&#xff09;提出的概念模型&#xff0c;用于描述和标准化电信或计算系统的通信功能&#xff0c;以实现不同通信系统之间的互操作性。该模型将通信系统划分…

【笔记】:更方便的将一个List中的数据传入另一个List中,避免多重循环

这里是 simpleInfoList 集合&#xff0c;记为集合A&#xff08;传值对象&#xff09; List<CourseSimpleInfoDTO> simpleInfoList courseClient.getSimpleInfoList(courseIds);if(simpleInfoListnull){throw new BizIllegalException("当前课程不存在!");}这…

Ubuntu上Jenkins自动化部署Gitee上VUE项目

文章目录 1.安装NodeJS插件2.配置全局工具配置-NodeJS环境变量3.新建自由风格的软件项目任务4.配置General配置丢弃旧的构建配置参数化构建过程 5.配置源码管理6.构建触发器7.设置构建环境8.配置构建步骤9.配置构建后操作10测试构建 前文链接&#xff1a; Ubuntu上Jenkins自动…

使用 OpenCV 通过 SIFT 算法进行对象跟踪

本文介绍如何使用 SIFT 算法跟踪对象 在当今世界&#xff0c;当涉及到对象检测和跟踪时&#xff0c;深度学习模型是最常用的&#xff0c;但有时传统的计算机视觉技术也可能有效。在本文中&#xff0c;我将尝试使用 SIFT 算法创建一个对象跟踪器。 为什么人们会选择使用传统的计…

深入Linux内核(进程篇)—进程切换之ARM体系架构 简单总结

context_switch函数完成Arm架构Linux进程切换&#xff0c;调用两个函数&#xff1a; 调用switch_mm() 完成用户空间切换&#xff0c;刷新I-CACHE&#xff0c;处理ASID和TLB&#xff0c;页表转换基址切换&#xff08;即把TTBR0寄存器的值设置为新进程的PGD&#xff09;&#xf…

应用多元统计分析--多元数据的直观表示(R语言)

例1.2 为了研究全国31个省、市、自治区2018年城镇居民生活消费的分布规律&#xff0c;根据调查资料做区域消费类型划分。 指标&#xff1a; 食品x1&#xff1a;人均食品支出(元/人) 衣着x2&#xff1a;人均衣着商品支出(元/人) 居住x3&#xff1a;人均居住支出(元/人) 生活x4…

智能驾驶规划控制理论学习-基于采样的规划方法

目录 一、基于采样的规划方法概述 二、概率路图&#xff08;PRM&#xff09; 1、核心思想 2、实现流程 3、算法描述 4、节点连接处理 5、总结 三、快速搜索随机树&#xff08;RRT&#xff09; 1、核心思想 2、实现流程 3、总结 4、改进RRT算法 ①快速搜索随机图&a…

Newtonsoft.Json

目录 引言 1、简单使用 1.1、官方案例 1.2、JsonConvert 2、特性 2.1、默认模式[JsonObject(MemberSerialization.OptIn/OptOut)] 2.2、序列化为集合JsonArrayAttribute/JsonDictionaryAttribute 2.3、序列化该元素JsonProperty 2.4、忽略元素JsonIgnoreAttribute 2.5、…

来,和同频的人一起学习论文#理解技术趋势

学习新技术&#xff0c;慢慢也有了施展拳脚的地方。今天我们给ComfyUI中文爱好者社区成员提供了一个工作机会&#xff0c;有需要可以联系我们的小助手&#xff1a; 相信这几天大家都看到了我们更新了些论文笔记出来&#xff0c;阅读1篇英文论文我们需要花几个小时&#xff0c;如…

STM32串口DMA发送接收(1.5Mbps波特率)机制

数据拷贝过程中不需要CPU干预&#xff0c;数据拷贝结束则通知CPU处理。 以115200bps波特率&#xff0c;1s传输11520字节&#xff0c;大约69us需响应一次中断&#xff0c;如波特率再提高&#xff0c;将消耗更多CPU资源 高波特率场景下&#xff0c;串口非常有必要使用DMA。 关…

C#使用iText7将多个PDF文档合并为单个文档

使用HtmlAgilityPack抓取并分析网页内容&#xff0c;然后再调用PuppeteerSharp将网页生成PDF文件&#xff0c;最终的成果如下图所示&#xff0c;得到将近120个pdf文档。能看&#xff0c;但是不方便&#xff0c;需要逐个打开文档才能看到所需的内容&#xff0c;最好能将这些文档…