首页 > 其他分享 >有关线段树的一些细节理解

有关线段树的一些细节理解

时间:2024-08-16 09:38:07浏览次数:8  
标签:int 线段 tr mid 细节 理解 add void

写在前面

本菜鸡线段树学了好多遍
但是每次写还是得很长时间
有时有一个细节还要琢磨半天
所以为了今后避免以上事情发生
本菜鸡决定将这么长时间以来对线段树的认识汇总
好日后清算

模板

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5;
int add[N*4],tr[N*4],a[N];//
int n,y,x,op,m,k;
void build(int k,int l,int r){
	if(l==r){
		tr[k]=a[l];
		return;
	}  
	int mid=(l+r)/2;
	build(2*k,l,mid);
	build(2*k+1,mid+1,r);
	tr[k]=tr[2*k]+tr[2*k+1];
}
void Add(int k,int l,int r,int v){
	tr[k]+=v*(r-l+1);
	add[k]+=v;
}
void pushdown(int k,int l,int r){
	if(!add[k]) return;//可写可不写
	int mid=(l+r)/2;
	Add(2*k,l,mid,add[k]);
	Add(2*k+1,mid+1,r,add[k]);
	add[k]=0;//标记下传完毕,本位值已正确
}
void longchange(int k,int l,int r,int x,int y,int v){
	if(x<=l&&r<=y){
		add[k]+=v;//这里为什么要写呢?
		tr[k]+=v*(r-l+1);//观察下面就return
		return;
	}
	pushdown(k,l,r);
	int mid=(l+r)/2;
	if(x<=mid) longchange(2*k,l,mid,x,y,v);
	if(y>mid) longchange(2*k+1,mid+1,r,x,y,v);
	tr[k]=tr[2*k]+tr[2*k+1];
}
int longquery(int k,int l,int r,int x,int y){
	if(x<=l&&r<=y){
		return tr[k];
	}
	pushdown(k,l,r);
	int res=0,mid=(l+r)/2;
	if(x<=mid) res+=longquery(2*k,l,mid,x,y);
	if(y>mid) res+=longquery(2*k+1,mid+1,r,x,y);
	return res;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	build(1,1,n);
	for(int i=1;i<=m;i++){
		scanf("%lld%lld%lld",&op,&x,&y);
		if(op==1){
			scanf("%lld",&k);
			longchange(1,1,n,x,y,k);
		}
		if(op==2){
			printf("%lld\n",longquery(1,1,n,x,y)); 
		}
	}
}

标签:int,线段,tr,mid,细节,理解,add,void
From: https://www.cnblogs.com/zcxnb/p/18362314

相关文章

  • zkw线段树
    事情的起因是我某天吃晚饭时打算找个电子榨菜,然后b站搜索线段树,看到了一个名叫zkw线段树(即非递归线段树),由于不是面向Oier的,所以饭后我又找了几个博客看,现在写下心得记录(其实只是不想在书签留3个位置给线段树)为什么要学习非递归线段树,这个问题大部分博客解释为普通线段树......
  • 机械学习—零基础学习日志(如何理解线性代数3)
    零基础为了学人工智能,正在快乐学习,每天都长脑子行列式最早行列式,是莱布尼茨用于判断,一个方程有没有解。例如,三元一次方程,如果有解,对应行列式就有值,但是如果无解,那么对应的行列式则为零。线性映射一个方程组可以写成上述的形式,而A就是线性映射。这里可以把向量x,理解为输入......
  • KMP算法——理解 next 数组
    !注意!本文与《王道》,《严书》有所不同,字符串均从第0位开始,next数组没有添加常数1。博客为梳理思路所用,难免纰漏,希望不吝赐教。在字符串匹配中,设m为待匹配的主串S长度,n为找寻的模式串T长度。如:在主串S='ababc'中寻找模式串T='abc'则字符串匹配算法返回S中第......
  • Css预编语言的理解?有哪些区别?
    Css作为一门标记性语言,语法相对简单,但同时也带来一些问题。需要书写大量看似没有逻辑的代码,不方便维护及扩展,不利于复用,Css预处理器便是针对上述问题的解决方案。Css预编译语言在前端里面有三大优秀的预编处理器,分别是:1、sass2、less3、stylus:变量:less声明的变量必须以@开......
  • OpenFeign 使用细节
    @EnableFeignClients注解配置项@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})@Documented@Import({FeignClientsRegistrar.class})public@interfaceEnableFeignClients{//和basePackages互为别名String[]value()default{};//......
  • 深入理解单元测试:技巧与最佳实践
    之前分享过如何快速上手开源项目以及如何在开源项目里做集成测试,但还没有讲过具体的实操。今天来详细讲讲如何写单元测试。......
  • md5sum+可执行文件 怎么理解?
    `md5sum`是一个在Unix、Linux以及其他类Unix系统中广泛使用的命令行工具,用于计算和校验文件的MD5哈希值。MD5哈希是一种广泛使用的加密哈希函数,可以产生一个128位(16字节)的哈希值(通常以32位的十六进制数表示),用于验证文件的完整性和一致性。 当你看到`md5sum`与“可......
  • SpringBoot整合MyBatis,入门教程,细节无敌,不能错过
    需求SpringBoot整合MyBatis。实现步骤搭建SpringBoot工程引入mybatis起步依赖、添加mysql驱动编写DataSource和MyBatis相关配置定义表和实体类编写dao和mapper文件/纯注解开发测试惨痛的教训同一个项目里,application.*文件只能有一个,如果有多个就会出现一些神奇问题......
  • 『线段树合并』Day7
    颓了一天了。md虽然还没有过线段树合并板题,但早就用过了。注意,单次合并复杂度是\(O(n\logn)\)的,但是一直合并,保证最终共有\(n\)个元素的话,总时间复杂度也是\(o(n\logn)\)的。不要理解成单次\(\logn\)。一个人千万不能忘记自己的初心,有时候需要静下心来想一想自己到底......
  • 线段树杂谈
    动态开点线段树引入普通的线段树写法有一个显然的缺点——空间。堆式存贮使得我们开线段树时需要用$4n$的空间。冗余空间高达$2n$。而且,在大多数情况下线段树中并不是每个节点都会被用到,这时我们就可以使用动态开点线段树,不仅所用的空间小,实现起来的代码也比普通线段树......