[数据结构]线段树讲解

前情提要

代码有点史,请见谅!
今天闲的没事把我私藏多年的线段树题拿出来,不难可以做一做。

讲解

线段树是一种存储方式。简单来说,就是在普通数组的基础上构建一个二叉树,如下图:
线段树图例1
由图可知每个结点的编号满足以下三式:

\[左子节点编号=当前节点编号\times 2 \]

\[右子节点编号=当前节点编号\times 2+1 \]

\[原数组所在节点编号\ge n \]

那么查找与赋值也就很简单了。


模板

单点查询

int find(int now,int l,int r,int pos){
	if(l==r){
		return t[now];
	}
	int mid=(l+r)>>1;
	if(pos<=mid){
		return find(ls,l,mid,pos);
	}else{
		return find(rs,mid+1,r,pos);
	}
}

区间查询

int find(int now,int l,int r,int L,int R){
	if(L<=l&&r<=R){
		return t[now];
	}
	int mid=(l+r)>>1;
	long long ans=0;
	if(L<=mid){
		ans+=find(ls,l,mid,L,R);
	}
	if(R>mid){
		ans+=find(rs,mid+1,r,L,R);
	}
	return ans;
}

单点修改

void add(int now,int l,int r,int pos,int v){
	if(l==r){
		t[now]+=v;
		return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid){
		add(ls,l,mid,pos,v);
	}else{
		add(rs,mid,r,pos,v);
	}
	pushup(now);
	return;                            
}

区间修改

void add(int now,int l,int r,int L,int R,int v){
	if(lazy[now]){
		t[now]+=lazy[now]*(r-l+1);
		if(l!=r) pushdown(now);
		else lazy[now]=0;
	}
	if(L<=l&&r<=R){
		if(l==r){
			t[now]+=v;
		}else{
			lazy[now]+=v;
		}
		return;
	}
	int mid=(l+r)>>1;
	if(L<=mid){
		add(ls,l,mid,L,R,v);
	}
	if(R>mid){
		add(rs,mid+1,r,L,R,v);
	}
	return ; 
}

后记

看到这里了,给个关注吧!

posted @ 2026-02-26 08:12  Co_led  阅读(4)  评论(0)    收藏  举报