线段树模板总结

线段树模板总结

线段树建图:
void build(int L;int R;int o)
{
if(L==R)
{
scanf("%lld",&sum[o]);
return;
}
int mid=(L+R)/2;
build(L,mid,o2);
build(mid+1,R,o
2+1);
sum[o]=sum[o2]+sum[o2+1];
}

————————————————————————————————————————
单点修改,区间查询
无lazy标记。
单点修改:
void update(int l,ll t,int L,int R,int o)
{
if(L==R)
{
sum[o]+=t;//对这个点进行修改
return;
}
int mid=(L+R)/2;
if(l<=mid)
update(l,t,L,mid,o2);//左子树
if(l>mid)
update(l,t,mid,R,o
2+1);//右子树
sum[o]=sum[o2]+sum[o2+1];//更新后修改父节点的和
}

区间查询:
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;//如果这个区间和目标区间毫不相干,返回0
int s=0;
if(tree[i2].r>=l) s+=search(i2,l,r);//如果这个区间的左儿子和目标区间又交集,那么搜索左儿子
if(tree[i2+1].l<=r) s+=search(i2+1,l,r);//如果这个区间的右儿子和目标区间又交集,那么搜索右儿子
return s;
}

————————————————————————————————————————
区间修改,单点查询;区间修改,区间查询
有lazy标记。
区间修改:
void update(int l,int r,ll t,int L,int R,int o)
{
/如果一个子区间完全在修改区间内,只需要修改这个子区间的
总和,不在下移。
/
if(l<=L&&r>=R)
{
lazy[o]+=t;//表示给每个节点存了多少值
sum[o]+=(R-L+1)t;//有多少节点就加多少,不在下移
return;
}
down(o,R-L+1);
int mid=(L+R)/2;
if(l<=mid)
update(l,r,t,L,mid,o
2);
if(r>mid)
update(l,r,t,mid+1,R,o
2+1);
sum[o]=sum[o
2]+sum[o*2+1];
}

lazy标记下移:
void down(int o,int s)
{
if(lazy[o])
{
lazy[o2]+=lazy[o];//标记移到左子树
lazy[o
2+1]+=lazy[o];//标记移到右子树
sum[o*2]+=(s-(s/2))lazy[o];//左子树有多少点就加多少
sum[o
2+1]+=(s/2)*lazy[o];//右子树有多少点就加多少
lazy[o]=0;//此节点清零
}
}

单点查询:
void query(ll &s,int l,int L,int R,int o)
{
if(L==R)
{
s=sum[o];//查到这个点后直接等于然后返回
return;
}
down(o,R-L+1);//查到lazy标记下的点,下移
int mid=(L+R)/2;
if(l<=mid)
query(s,l,L,mid,o2);
if(l>mid)
query(s,l,mid+1,R,o
2+1);
}

区间查询:
void query(ll &s,int l,int r,int L,int R,int o)
{
//int &s可以使得s的值不用返回,在主函数中直接使用
if(l<=L&&r>=R)//当查询区间在当前区间内时
{
s=s+sum[o];//将此节点的数值加上去
return;
}
down(o,R-L+1);//当查询到lazy标记下面的点,下移
int mid=(L+R)/2;
if(l<=mid)
query(s,l,r,L,mid,o2);//左子树
if(r>mid)
query(s,l,r,mid+1,R,o
2+1);//右子树
}

————————————————————————————————————————

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值