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

news2024/12/23 8:16:21

引入: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;
	} 
} 

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

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

相关文章

2024全国水科技大会暨高氨氮废水厌氧氨氧化处理技术论坛(四)

一、会议背景 为积极应对“十四五”期间我国生态环境治理面临的挑战&#xff0c;加快生态环境科技创新&#xff0c;构建绿色技术创新体系&#xff0c;全面落实科学技术部、生态环境部等部委编制的《“十四五”生态环境领域科技创新专项规划》&#xff0c;积极落实省校合作&…

物联网与智慧城市的融合:构建智能化、便捷化、绿色化的城市未来

一、引言 随着科技的飞速发展和城市化的不断推进&#xff0c;物联网技术正逐步渗透到城市的各个领域&#xff0c;成为推动智慧城市建设的核心力量。物联网与智慧城市的融合&#xff0c;不仅为城市治理提供了高效、智能的解决方案&#xff0c;也为市民的生活带来了前所未有的便…

Docker Swarm全解析:实现微服务高可用与故障转移的秘密武器

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Docker入门到精通》 《k8s入门到实战》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、基本概念和介绍 1、Docker Swarm 是什么&#xff0c;它与 …

APP自动化测试-入门示例

入门示例 通过上一篇博客APP自动化测试介绍-CSDN博客的学习&#xff0c;相信大家对APP自动化测试已经有了一定的了解&#xff0c;下面演示一下入门示例 1. 配置Appium 1.1. 点击Appium图标&#xff0c;打开服务器&#xff1a; 1.2. 点击Edit Configurations,进入配置页面&am…

elment-ui table表格排序后 清除排序箭头/恢复默认排序 的高亮样式

问题描述&#xff1a; 1.默认排序是按照名称升序排列&#xff08;图一&#xff09; 2.在选择了筛选项以及其他排序方式之后&#xff0c;箭头高亮是这样的&#xff08;图二&#xff09; 3.当我点击清空按钮后&#xff0c;类型清空了&#xff0c;并且传给后端的排序方式是名称/升…

文本多分类

还在用BERT做文本分类&#xff1f;分享一套基于预训练模型ERNIR3.0的文本多分类全流程实例【文本分类】_ernir 文本分类-CSDN博客 /usr/bin/python3 -m pip install --upgrade pip python3-c"import platform;print(platform.architecture()[0]);print(platform.machine…

StarRocks实战——表设计规范与监控体系

目录 前言 一、StarRocks表设计 1.1 字段类型 1.2 分区分桶 1.2.1 分区规范 1.2.2 分桶规范 1.3 主键表 1.3.1 数据有冷热特征 1.3.2 大宽表 1.4 实际案例 1.4.1 案例一&#xff1a;主键表内存优化 1.4.2 案例一&#xff1a;Update内存超了&#xff0c;导致主键表导…

【AI Agent系列】【MetaGPT多智能体学习】5. 多智能体案例拆解 - 基于MetaGPT的智能体辩论(附完整代码)

本系列文章跟随《MetaGPT多智能体课程》&#xff08;https://github.com/datawhalechina/hugging-multi-agent&#xff09;&#xff0c;深入理解并实践多智能体系统的开发。 本文为该课程的第四章&#xff08;多智能体开发&#xff09;的第三篇笔记。主要是对课程刚开始环境搭…

YOLOv9有效提点|加入SE、CBAM、ECA、SimAM等几十种注意力机制(一)

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、本文介绍 本文将以SE注意力机制为例&#xff0c;演示如何在YOLOv9种添加注意力机制&#xff01; 《Squeeze-and-Excitation Networks》 SENet提出…

【六袆 - React】Next.js:React 开发框架;Next.js开发框架的特点

Next.js&#xff1a;React 开发框架 Next.js的特点 1.直观的、基于页面的路由系统&#xff08;并支持动态路由&#xff09; Next.js 提供了基于文件系统的路由&#xff0c;意味着你可以通过创建页面文件来定义路由。 伪代码示例&#xff1a; // pages/index.js export defa…

css【详解】—— 圣杯布局 vs 双飞翼布局 (含手写清除浮动 clearfix)

两者功能效果相同&#xff0c;实现方式不同 效果预览 两侧宽度固定&#xff0c;中间宽度自适应&#xff08;三栏布局&#xff09;中间部分优先渲染允许三列中的任意一列成为最高列 圣杯布局 通过左右栏填充容器的左右 padding 实现&#xff0c;更多细节详见注释。 <!DOCTYP…

day03-Vue-Element

一、Ajax 1 Ajax 介绍 1.1 Ajax 概述 概念&#xff1a;Asynchronous JavaScript And XML&#xff0c;异步 的 JavaScript 和 XML。 作用&#xff1a; 数据交换&#xff1a;通过 Ajax 可以给服务器发送请求&#xff0c;并获取服务器响应的数据。异步交互&#xff1a;可以在 不…

排序(2)——希尔排序

希尔排序&#xff08;缩小增量排序&#xff09; 基本思想 希尔排序法又称缩小增量法。希尔排序法的基本思想是&#xff1a;先选定一个整数&#xff0c;把待排序文件中所有记录分成个组&#xff0c;所有距离为的记录分在同一组内&#xff0c;并对每一组内的记录进行排序。然后&…

lotus 从矿工可用余额扣除扇区质押

修改 miner配置文件 # Whether to use available miner balance for sector collateral instead of sending it with each message## type: bool# env var: LOTUS_SEALING_COLLATERALFROMMINERBALANCE#CollateralFromMinerBalance falseCollateralFromMinerBalance true质押金…

手写数字识别(慕课MOOC人工智能之模式识别)

问题&#xff1a;手写数字识别 数据集 数据集链接请点击我 代码 %mat2vector.m function [data_] mat2vector(data,num)[row,col,~] size(data);data_zeros(num,row*col);for page 1:numfor rows 1:rowfor cols1:coldata_(page,((rows-1)*colcols)) im2double(data(rows,cols…

应用稳定性优化1:ANR问题全面解析

闪退、崩溃、无响应、重启等是应用稳定性常见的问题现象&#xff0c;稳定性故障大体可归类为ANR/冻屏、Crash/Tombstone、资源泄露三大类。本文通过对三类故障的产生原因、故障现象、触发机制及如何定位等&#xff0c;展开深度解读。 本文将详解ANR类故障&#xff0c;并通过一…

java数据结构与算法刷题-----LeetCode437. 路径总和 III(前缀和必须掌握)

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 深度优先2. 前缀和 1. 深度优先 解题思路&#xff1a;时间复…

图书推荐||Word文稿之美

让你的文档从平凡到出众&#xff01; 本书内容 《Word文稿之美》是一本全面介绍Word排版技巧和应用的实用指南。从初步认识数字排版到高效利用模板、图文配置和表格与图表的排版技巧&#xff0c;再到快速修正错误和保护文件&#xff0c;全面系统地讲解数字排版的技术和能力&…

多行业万能预约门店小程序源码系统 支持多门店预约小程序 带完整的安装代码包以及搭建教程

随着消费者对于服务体验要求的不断提升&#xff0c;门店预约系统成为了许多行业提升服务质量、提高运营效率的重要工具。然而&#xff0c;市面上的预约系统往往功能单一&#xff0c;无法满足多行业、多场景的个性化需求。下面&#xff0c;小编集合了多年的行业经验和技术积累&a…

Linux 安装k8s

官网 常见的三种安装k8s方式 1.kubeadm 2.kops&#xff1a;自动化集群制备工具 3.kubespray&#xff1a; 提供了 Ansible Playbook 下面以kubeadm安装k8s kubeadm的安装是通过使用动态链接的二进制文件完成的&#xff0c;目标系统需要提供 glibc ##使用 ss 或者 netstat 检测端…