线段树笔记1:线段树的基本操作
线段树的基本操作模板
目录
1、 创建线段树
2、 单点修改
3、 单点修改基础的区间查询及单点查询
4、 区间修改
5、 区间修改基础的区间查询
1、建树(build)
void build(int l,int r,int k)
{
if(l==r){
tree[k]=a[l];
return ;
}
int mid=l+r>>1;
bulid(l,mid,k*2);
bulid(mid+1,r,k*2+1);
tree[k]=tree[k*2]+tree[k*2+1];
}
2、单点修改
void updata(int l,int r,int pos,int value,int k)
{
if(l==r){
tree[k]+=value;
return ;
}
int mid=l+r>>1;
if(pos<=mid)updata(l,mid,pos,value,k*2);
else updata(mid+1,r,pos,value,k*2+1);
tree[k]=tree[k*2]+tree[k*2+1];
}
3、单点修改基础的区间查询及单点查询
void query(int l,int r,int L,int R,int k)//令L==R即可单点查询
{
if(L<=l&&r<=R){
sum+=tree[k];
return ;
}
int mid=l+r>>1;
if(L<=mid)query(l,mid,L,R,k*2);
if(R>mid)query(mid+1,r,L,R,k*2+1);
}
4、区间修改
void updata(int l,int r,int L,int R,long long value,int k)
{
if(L<=l&&r<=R){
tree[k]+=value*(r-l+1);
lazy[k]+=value;
return ;
}
if(lazy[k]){
int mid=(l+r)>>1;
lazy[k*2]+=lazy[k];
lazy[k*2+1]+=lazy[k];
tree[k*2]+=lazy[k]*(mid-l+1);
tree[k*2+1]+=lazy[k]*(r-mid);
lazy[k]=0;
}
int mid=(l+r)>>1;
if(L<=mid)updata(l,mid,L,R,value,k*2);
if(R>mid)updata(mid+1,r,L,R,value,k*2+1);
tree[k]=tree[k*2]+tree[k*2+1];
}
5、区间修改基础的区间查询
void query(int l,int r,int L,int R,int k)
{
if(L<=l&&r<=R){
sum+=tree[k];
return ;
}
if(lazy[k]){
int mid=(l+r)>>1;
lazy[k*2]+=lazy[k];
lazy[k*2+1]+=lazy[k];
tree[k*2]+=lazy[k]*(mid-l+1);
tree[k*2+1]+=lazy[k]*(r-mid);
lazy[k]=0;
}
int mid=l+r>>1;
if(L<=mid)query(l,mid,L,R,k*2);
if(R>mid)query(mid+1,r,L,R,k*2+1);
}