这个博主的线段树我觉得讲的很细了
建树
struct node{
ll l,r;
ll sum,mlz,plz;
}tree[4*maxn];
inline void bulid(int i,int l.int r)
{
tree[i].l=1;
tree[i].r=r;
if(l==r){
tree[i].sum=input[i];
return ;
}
int min=(l+r)>>1;
bulid(i*2,l,min);
bulid(i*2+1,min+1,r);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
区间查询,单点修改
inline int search(int i,int l,int r){
if(tree[i].l>=l&&tree[i].r<=r)return tree[i].sum;
if(tree[i].r<l||tree[i].l>r)return 0;
int sum=0;
if(tree[i*2].r>=l)sum+=search(i*2,l,r);
if(tree[i*2+1].l<=r)sum+=search(i*2+1,l,r);
return sum;
}
inline void add(int i,int dis,int k)
{
if(tree[i].l==tree[i].r)
{
tree[i].sum+=k;
return;
}
if(dis<=tree[i*2].r)add(i*2,dis,k);
else add(i*2+1,dis,k);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
return ;
}
区间修改,单点查询
inline void add(int i,int l,int r,int k)
{
if(tree[i].l>=l&&tree[i].r<=r){
tree[i].num+=k;
return;
}
if(tree[i*2].r>=l)add(i*2,l,r,k);
if(tree[i*2+1].l<=r)add(i*2+1,l,r,k);
}
void search(int i,int dis){
ans+=tree[i].num;
if(dis<=tree[i*2].r)
search(i*2,dis);
if(dis>=tree[i*2+1].l)
search(i*2+1,dis);
}
区间修改,区间查询(带pushdown)
void push_down(int i)
{
if(tree[i].lz)
{
tree[i*2].lz+=tree[i].lz;
tree[i*2+1].lz+=tree[i].lz
int mid=(tree[i].l+tree[i].r)/2;
tree[i*2].sum+=tree[i].lz*(mid-tree[i*2].l+1);
tree[i*2+1].sum+=tree[i].lz*(tree[i*2+1].r-mid);
tree[i].lz=0;
}
return 0;
}
void add(int i,int l,int r,int k){
if(tree[i].r<=r&&tree[i].l>=l)
{
tree[i].sum+=k*(tree[i].r-tree[i].l+1);
tree[i].lz+=k;
return;
}
push_back(i);
if(tree[i*2].r>=l)add(i*2,l,r,k);
if(tree[i*2+1].l<=r)add(i*2+1,l,r,k);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
return 0;
}
inline int search(int i,int l,int r){
if(tree[i].l>=l&&tree[i].r<=r)return tree[i].sum;
if(tree[i].r<l||tree[i].l>r)return 0;
push_back(i);
int sum=0;
if(tree[i*2].r>=l)sum+=search(i*2,l,r);
if(tree[i*2+1].l<=r)sum+=search(i*2+1,l,r);
return sum;
}