[数据结构]线段树讲解
前情提要
代码有点史,请见谅!
今天闲的没事把我私藏多年的线段树题拿出来,不难可以做一做。
讲解
线段树是一种存储方式。简单来说,就是在普通数组的基础上构建一个二叉树,如下图:

由图可知每个结点的编号满足以下三式:
\[左子节点编号=当前节点编号\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 ;
}

浙公网安备 33010602011771号