线段树

本人深受动态开点的影响(动态开点好处多

决定将线段树写法全部变成动态开点,例如build函数

void build(int &u,int l,int r)
{
  if(!u) u=++num;
  tree[u].l=l;
  tree[u].r=r;
  if(l==r)
  {
    tree[u].val=v[l];
    return ;
  }
  int mid=(l+r)>>1;
  build(tree[u].lson,l,mid);
  build(tree[u].rson,mid+1,r);
  pushup(u);
}

至于其他的函数都是一样的qwq

省事了不少

接着总结一些没用的东西

众所周知,线段树可以改的地方就是pushup和pushdown

pushdown就是改标记,常见的线段树标记:

和,乘
异或和
前后缀
区间01翻转
区间染色

对于pushup的应用就是利用线段树算出当前的区间答案,然后将不可以快速合并的条件转化

转化成仅仅针对于左区间的答案和右区间递归的结果

关于可持久化有人说很难打,我觉得还好啊,build都不需要

下面粘贴一下modify

int modify(int last,int l,int r,int x)
{
	int now=++cnt;
	if(l==r)
	{
    //do something
		return now;
	}
	int mid=(l+r)>>1;
	if(x<=mid)
	{
		tree[now].lson=modify(tree[last].lson,l,mid,x);
		tree[now].rson=tree[last].rson;
	}
	else
	{
		tree[now].rson=modify(tree[last].rson,mid+1,r,x);
		tree[now].lson=tree[last].lson;
	}
	return now;
}

不麻烦吧qwq

普通线段树还有啥用法希望dalao指点

原文地址:https://www.cnblogs.com/zzqdeco/p/12546488.html