本文会持续更新,时间看作者心情。
懒操作
懒操作是线段树的优点,也是难点。
简单介绍
//树结构
struct tree
{
int v; //结点的值
int lz;//lazy缩写,表示是否可以进行懒操作
}tr[N];
通常在题目中会对区间做更新操作,如果有结点刚好代表更新的区间,那么可以仅仅对该区间的结点进行更新操作,并且对该结点做一个标记,表示这个结点更新过,然后对这个结点的子结点便不再更新。
比如:要把6到10的值改为100,只要找到区间[6,10],把该结点的值改为100即可。输出时,遍历到有标记的[6,10]结点就输出10-6+1=5个tr[3].v
实际往往是进行多次操作,如果第一步把[6,10]改为100,再把[6,8]改为200,那么输出时如果只输出结点[6,10]是不行的,因此需要在懒操作之前扩展结点。
void lazy(int d)//懒操作de扩展
{
if(tr[d].lz)
{
tr[lc].lzx = tr[rc].lzx = true;
tr[lc].v = tr[rc].v = tr[d].v;
tr[d].lzx = false;//生效完还原
}
}
简单核心代码
懒操作的要点在于标记和扩展,如果找到对应的区间,就先标记好,到时如果需要更新之前标记好的结点下的子结点,可以用lazy()函数自动扩展。函数如下
//树结构
struct tree
{
int v; //结点的值
int lz;//lazy缩写,表示是否可以进行懒操作
}tr[N];
void lazy(int d)//懒操作de扩展
{
if(tr[d].lz)
{
tr[lc].lzx = tr[rc].lzx = true;
tr[lc].v = tr[rc].v = tr[d].v;
tr[d].lzx = false;//生效完还原
}
}
void function(int d, int l, int r, int left, int right, int x)
{
if(l == left && r == right)
{
......
tr[d].lz = ture;//懒操作标记
......
}
lazy();
}
题目
看不懂当然是因为没有题目来加强啦。请点击下一篇的线段树练习。
上一篇:(一)线段树入门–区间最值查询
下一篇: 线段树练习题–HDU(4902)